在使用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);
}
Row的声明:
typedef struct {
char** columns;
unsigned short int numcol;
} Row;
Row* rows = NULL;
更糟糕的是,这个程序有时会在free(&rows[i])
引起glibc错误,抱怨双重免费。我是C的新手,并且会感谢有人可能提出的任何指针(咳)。
答案 0 :(得分:8)
执行rows[rowcnt++] = *row;
可以有效地复制您分配的内存。您的数组行应该是一个指针数组。也像Oli Chalesworth指出的那样,对于所有列,您可以免费使用列。
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);
}
答案 1 :(得分:5)
对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++;
答案 2 :(得分:-6)
也许我是在密集,但这不是完全没必要的吗?无论如何,一旦程序退出,你的所有记忆都将被释放。