我正在尝试创建一个结构网格的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/

10-15 16:40