我正在尝试创建一个结构网格的2d数组,并通过地址清理器获得内存泄漏警告,最后在某些情况下获得seg错误。
我的代码中可能有各种各样的原因,但是我想知道这里出了什么问题,我会找到正确的方向来修复剩下的部分。
我是新的C,因此对内存管理,所以所有的反馈是欢迎和赞赏!
void createGridArray(atom_t* ATOM) {
ATOM -> grid = (grid_t**) malloc(WIDTH * sizeof(grid_t*));
grid_t *nullGrid = malloc(sizeof(grid_t));
grid_t temp = {NULL, 0};
*nullGrid = temp;
for (int i = 0; i < WIDTH; i++) {
(ATOM -> grid)[i] = malloc(HEIGHT * sizeof(grid_t));
for (int j = 0; j < HEIGHT; j++) {
(ATOM -> grid)[i][j] = *nullGrid;
}
}
//free(nullGrid); <- do I do this now?
return;
}
最佳答案
首先,不要从malloc()
中进行返回。它在C中不是必需的,并且可以掩盖严重的错误。
其次,不要将类型硬编码到malloc()
调用中。例如,
ATOM->grid = (grid_t**) malloc(WIDTH * sizeof(grid_t*));
将被替换为
ATOM->grid = malloc(WIDTH * sizeof(*(ATOM->grid)));
这可以确保分配的内存是所需的大小,而不管
ATOM->grid
指向什么。要回答您的问题,要释放所有内存,您需要将
NULL
返回的每个非malloc()
指针传递给free()
。就一次。所以,如果你这样分配
ATOM->grid = malloc(WIDTH * sizeof(*(ATOM->grid)));
grid_t *nullGrid = malloc(sizeof(*nullGrid));
grid_t temp = {NULL, 0};
*nullGrid = temp;
for (int i = 0; i < WIDTH; i++)
{
(ATOM -> grid)[i] = malloc(HEIGHT * sizeof(*((ATOM->grid)[i])));
for (int j = 0; j < HEIGHT; j++) {
(ATOM -> grid)[i][j] = *nullGrid;
}
一种方法是
for (int i = 0; i < WIDTH; i++)
{
free((ATOM -> grid)[i]);
}
free(ATOM->grid);
free(nullGrid);
在这种情况下,您不能在任何
free(ATOM->grid)
之前安全地free((ATOM -> grid)[i])
(除非您将所有(ATOM->grid)[i]
存储在其他地方,这有点违背了这一点)。个体(ATOM->grid)[i]
可以按任意顺序被释放(只要每个都被释放一次)。最后,检查
malloc()
返回的指针。当它失败时返回NULL
,而取消对NULL
指针的引用会产生未定义的行为。关于c - C中的内存泄漏,函数内部的malloc,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43252469/