内存泄漏在C,malloc里面的函数

时间:2017-04-06 10:26:02

标签: c memory-leaks malloc

我正在尝试创建一个struct grid_t的二维数组,并通过地址消毒器获取内存泄漏警告,并在某些条件下最终出现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;
}

3 个答案:

答案 0 :(得分:3)

首先,不要从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指针会给出未定义的行为。

答案 1 :(得分:0)

是的,您需要free(nullGrid);来避免内存泄漏。

但实际上您可以将代码简化为:

void createGridArray(atom_t* ATOM) {
  ATOM -> grid = (grid_t**) malloc(WIDTH * sizeof(grid_t*));

  grid_t nullGrid = {NULL, 0};

  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;
    }
  }
}

这里需要mallocing nullGrid。顺便说一句,void函数末尾的return是隐含的。

你也不会这样做:

void Foo()
{
   ...
   int *temp = malloc(sizeof(int));
   *temp = ...;
   ...
      bar = *temp;

   ...
   free(temp);
}

而是:

void Foo()
{
   ...
   int temp
   temp = ...;
   ...
      bar = temp;

   ...
}

答案 2 :(得分:0)

当您将其视为“贷款”时,C内存分配会更容易。

不知何故,当你调用malloc()时系统会给你一些内存,而你必须用free()给它回来。