Выделить массив динамической структуры

Я пытаюсь использовать динамический массив структуры, содержащей динамический массив. Выделение выполняется в функции build_resuts, а память освобождается в функции free_data.

Я делаю это правильно?

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);
}

Я видел образцы, где распределение было похоже:

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

Так что я не уверен, как я должен делать и почему:

1 ответ

(Кстати, в C вам не нужно приводить возвращаемое значение malloc() : Если он не скомпилируется без приведения, вы ошиблись)

Код, который вы находите странным, включает в себя размещение всех массивов в одном буфере: это обеспечивает лучшую "локальность памяти" (т. Е. Связанные вещи, находящиеся вместе в памяти), за счет невозможности индивидуального изменения массивов: это полезно для производительности, но только полезно для данных, которые инициализируются один раз и не изменяются со временем (или, по крайней мере, размер которых не изменяется со временем).

Это также позволяет вам освободить все это только одним звонком free() и делает обработку ошибок намного проще (так как вам не нужно проверять, что все malloc() вызовы в цикле успешны, и если нет, освобождают все вызовы, которые были успешны до сих пор, а не другие...)

Другие вопросы по тегам