C释放指针指针

时间:2010-12-04 18:43:26

标签: c pointers free

在我的代码中,我有几个指针指针(例如float **变量),我似乎遇到了释放内存的问题,以免造成内存泄漏。这是我写的代码:

float *one, **part1, **part2;

one = malloc(sizeof(&one) * nx * nx);
part1 = malloc(sizeof(&part1) * nx);

if(one == NULL || part1 == NULL) {
 printf("Memory error.\n");
 exit(2);
}

for(k = 0; k < nx; k++)
 part1[k] = &one[k * nx];

one = malloc(sizeof(&one) * nx * nx);
part2 = malloc(sizeof(&part2) * nx);

if(one == NULL || part2 == NULL) {
 printf("Memory error.\n");
 exit(2);
}

for(k = 0; k < nx; k++)
 part2[k] = &one[k * nx];

... (Other code here)

for(k = 0; k < nx; k++) {
 free(part1[k]);
 free(part2[k]);
}

free(one);
free(part1);
free(part2);

此代码运行,正确执行计算,但随后在自由循环中出错。它适用于k = 0,但是当试图释放part1 [1]和part2 [1]时,它会给我“glibc detected”错误。

3 个答案:

答案 0 :(得分:2)

首先:

one = malloc(sizeof(&one) * nx * nx);
part1 = malloc(sizeof(&part1) * nx);

这些应该是

one = malloc(sizeof(*one) * nx * nx);
part1 = malloc(sizeof(*part1) * nx);

您想要分配一堆floatfloat * s,而不是float **float *** s

其次,您进行4次分配 - 您在one中分配part1和索引, 然后再次分配one,(忘记旧地址),并在part2中将索引编入其中。

这意味着您应该有4个free() s:part1part2以及one指向的两个内存块。因为您覆盖了第一个one,所以您丢失了该指针而无法直接free()它。幸运的是,您确实将该指针保存在part1[0]中,并且可以将其用于指向所有内存的free()

另一种(可能更清晰,更惯用)的选择是以不同的方式分配。分配part1,然后循环以分配每个part1[k],并为part2分配相同内容。

答案 1 :(得分:1)

您只有4次malloc来电,因此您应该只有4次free来电。你从来没有在一个循环中分配任何东西,那你为什么要在一个循环中解放?

part1[k]part2[k]从未自行分配,只是指向分配给one的内存区域,因此您应该只释放one。此外,这里有内存泄漏:

one = malloc(sizeof(&one) * nx * nx);
part1 = malloc(sizeof(&part1) * nx);

...

// *** You just lost the previous old pointer here *** //
one = malloc(sizeof(&one) * nx * nx);
part2 = malloc(sizeof(&part2) * nx);

您的代码适用于k = 0的原因是因为part1[0] == &one[0] == one,即part1[0]实际上指向one块的开头 - 通过释放它,您可以释放整个街区。

而且我不确定你的sizeof意味着什么。我猜你想要分配nx * nx浮点数 - 如果是的话,那应该是sizeof(*one) - *one是浮点数,但&oneone的地址1}},这是一个float **指针。


你真的想做这样的事情:

one1 = malloc(sizeof(*one) * nx * nx);
part1 = malloc(sizeof(*part1) * nx);

...

for(k = 0; k < nx; k++)
 part1[k] = &one1[k * nx];

...

free(part1);
free(one1);

答案 2 :(得分:1)

看看你正在做多少malloc,以及你正在做多少次释放。数字不匹配。

通常,您无法释放malloc'd结构的一部分。你只能释放它。所以最后你需要更像的东西:

... (Other code here)
/* four mallocs so four frees */
free(part1[0]);
free(part2[0]);
free(part1);
free(part2);