1

I'm trying to use dynamic array of a structure containning dynamic array. The allocation is done in the function build_resuts and the memory is freed in the function free_data.

Am I doing this correctly ?

typedef struct InputResultsLine 
{
    long registered;
    long *candidates;
} InputResultsLine;

void func()
{
    InputResultsLine *data, totals;
    int nbPollingPlaces = 10;

    build_results(&data, &totals,  5, nbPollingPlaces);     

    free_data(&data, &totals, nbPollingPlaces); 
}

void build_results(InputResultsLine **data, InputResultsLine *totals, int nbCandidates, int nbPollingPlaces)
{   
    int i;
    InputResultsLine *ptrCurrentLine;

    totals->candidates = (long*) malloc(nbCandidates * sizeof(long));       

    *data = (InputResultsLine*) malloc(nbPollingPlaces * sizeof(InputResultsLine));

    for(i = 0; i < nbPollingPlaces; i++)
    {       
        ptrCurrentLine = &((*data)[i]);
        ptrCurrentLine->candidates = (long*) malloc(nbCandidates * sizeof(long));

        // [...]    
    }   
}

void free_data(InputResultsLine **data, InputResultsLine *totals, int nbPollingPlaces)
{
    int i;  

    for(i = 0; i < nbPollingPlaces; i++)
    {
        free(((*data)[i]).candidates);
    }

    free(totals->candidates);
    free(*data);
}

I saw samples where the allocation was like :

*data = (InputResultsLine*) malloc(nbPollingPlaces * (sizeof(InputResultsLine) + nbCandidates * sizeof(long)));

So i'm not sure how I should do and why :

Marien
  • 117
  • 5

1 Answers1

0

(BTW, in C you don't need to cast the return value of malloc(): If it doesn't compile without a cast, you've made a mistake)

The code you find weird involves allocating all arrays in a single buffer: This allows for better "memory locality" (i.e. related things being together in memory) at the price of not being able to modify arrays individually: It's good for performance but only useful for data that is initialized once and does not change over time (or at least, whose size does not change over time).

It also allows you to free the whole thing with only one call to free() and makes error handling much simpler (since you don't have to check that all malloc() calls in a loop succeed, and if not, free all calls that had succeeded so far and not others...)

Medinoc
  • 6,577
  • 20
  • 42