【发布时间】:2020-05-14 15:53:20
【问题描述】:
当我遇到以下问题时,我正在使用 C 代码。我有一个看起来像这样的代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct a {
int n1;
int n2;
} el;
typedef struct list {
el *elements;
int nElements;
} list;
void copyList(list in, list *out) {
int i;
for(i = 0; i < in.nElements; i++) {
out->elements = realloc(out->elements,sizeof(el)*(out->nElements + 1));
out->elements[i] = in.elements[i];
out->nElements = out->nElements + 1;
}
}
void initList(list *l) {
l->nElements = 0;
l->elements = NULL;
}
void freeList(list *l) {
l->nElements = 0;
if(l->elements != NULL) {
free(l->elements);
l->elements = NULL;
}
}
void testRecur(int i, list l) {
list l1;
if(i > 0) {
initList(&l1);
copyList(l,&l1);
// freeList(&l);
testRecur(i-1,l1);
testRecur(i-2,l1);
// freeList(&l1);
}
else {
// freeList(&l);
}
}
int main(void) {
list l1;
list l2;
el element;
initList(&l1);
initList(&l2);
l1.elements = malloc(sizeof(el)*2);
l1.nElements = 2;
element.n1 = 1;
element.n2 = 2;
l1.elements[0] = element;
element.n1 = 3;
element.n2 = 4;
l1.elements[1] = element;
testRecur(10,l1);
// freeList(&l1);
return 0;
}
这是一个简单的代码,递归地复制一个列表一定次数。它没有任何意义,但很容易解释这个概念。问题是:我应该在哪里拨打free 电话?我已经尝试了注释点的所有组合,但我最终遇到了双重释放错误(*** Error in ./a.out: double free or corruption (fasttop): 0x0000000001ecd010 ***)或valgrind 的内存泄漏检测(使用以下参数:valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes ./a.out)。有没有办法不泄漏内存(至少根据 valgrind)?
【问题讨论】:
-
free(&l1);-->free(l1.elements); -
释放与分配
malloc结果相同的东西。 -
关于:
out->elements = realloc(out->elements,sizeof(el)*(out->nElements + 1));调用realloc()时可能会失败。将返回的指针保存在“临时”指针检查 (!=NULL) 中,并且仅当不是 NULL 时,将该指针分配给目标变量。out->elements如果 ==NULL,则调用perror( "realloc failed" );注意一旦realloc()失败,它将(可能)继续失败。所以建议“清理”并致电exit( EXIT_FAILURE );