C утечка памяти, несмотря на
В отладке моей программы с Valgrind я обнаружил утечку памяти, несмотря на то, что, как я думал, были эффективными призывами к бесплатному. Во-первых, код, который выделяет память и сохраняет ее:
row = malloc(sizeof(Row));
row->columns = malloc(sizeof(char*) * headcnt);
row->numcol = 0;
...
row->numcol = colcnt;
rows = realloc(rows, (rowcnt+1) * sizeof(Row));
rows[rowcnt++] = *row;
Код, ответственный за освобождение памяти:
void cleanUp(){
int i = 0;
int j = 0;
for (i = 0; i < rowcnt; i++){
for (j = 0; j < rows[i].numcols; j++){
free(rows[i].columns[j]);
}
free(&rows[i]);
}
free(rows);
exit(0);
}
Объявление строки:
typedef struct {
char** columns;
unsigned short int numcol;
} Row;
Row* rows = NULL;
Хуже того, эта программа иногда вызывает ошибку glibc в free(&rows[i])
, которая жалуется на двойную свободную. Я новичок в C, и буду благодарен за любые указатели (гм), которые могут быть у кого-то.
Ответы
Ответ 1
Выполнение rows[rowcnt++] = *row;
эффективно делает копию выделенной вами памяти. Строки массива должны быть массивом указателей. Также, как отметил Оли Чалсуорт, вы бесплатно для столбцов должны быть свободными для всех столбцов.
rows = malloc(count * sizeof(Row*)); // This is probably done somewhere
row->columns = malloc(sizeof(char*) * headcnt);
row->numcol = 0;
...
row->numcol = colcnt;
rows = realloc(rows, (rowcnt+1) * sizeof(Row*));
rows[rowcnt++] = row;
Теперь, если ваша очистка
void cleanUp(){
int i = 0;
int j = 0;
for (i = 0; i < rowcnt; i++){
free(rows[i]->columns);
}
free(rows);
exit(0);
}
Ответ 2
Каждый вызов malloc
(или realloc
) должен совпадать с соответствующим вызовом free
. Если вы динамически выделяете массив таким образом:
int *p = malloc(sizeof(int) * NUM);
Вы освобождаете его так:
free(p);
Не так:
for (int i = 0; i < NUM; i++)
{
free(p[i]);
}
Похоже, вы делаете это неправильно. Я подозреваю, что ваш код очистки должен быть:
void cleanUp(){
int i = 0;
int j = 0;
for (i = 0; i < rowcnt; i++){
for (j = 0; j < rows[i].numcols; j++){
free(rows[i].columns[j]); // Free whatever rows[i].columns[j] points to
}
free(rows[i].columns); // Matches row->columns = malloc(sizeof(char*) * headcnt);
}
free(rows); // Matches rows = realloc(rows, (rowcnt+1) * sizeof(Row));
exit(0);
}
Кроме того, нет способа сопоставления row = malloc(sizeof(Row));
. Я подозреваю, что ваш код распределения должен быть:
row->numcol = colcnt;
rows = realloc(rows, (rowcnt+1) * sizeof(Row));
rows[rowcnt].columns = malloc(sizeof(char*) * headcnt);
rows[rowcnt].numcol = 0;
rowcnt++;
Ответ 3
Может быть, я плотный, но разве это совершенно не нужно? В любом случае вся ваша память будет выпущена, как только программа выйдет.