【问题标题】:How can i correct this memory leak?我该如何纠正这种内存泄漏?
【发布时间】:2021-01-04 16:12:26
【问题描述】:

这是我使用 malloc 为 C 中的二维数组分配内存并释放它的代码。 N是用户给的数字

R = malloc(N * sizeof(int *)); // start of memory allocating for **R
if (R == NULL) { 
  return -1;
}

for (i = 0; i <= N; i++) {
  *(R+i) = malloc(N * sizeof(int));
  if (*(R + i) == NULL) {
    return -1;
  }
} // end of memory allocating for **R 

for (i = 0 ; i < N; i++){
  free(R[i]);
  free(R);
}

程序完成后,我得到这个错误:double free or corruption (out) Aborted (core dumped)

通过使用 valgrind 进行调试,我收到以下消息:12 bytes in 1 blocks are definitely lost in loss record 1 of 1

在这行代码中检测到此泄漏(根据 valgrind):*(C+i) = malloc(N * sizeof(int));

关于如何修复它的任何帮助?

【问题讨论】:

标签: c malloc free


【解决方案1】:

我收到此错误:双重释放或损坏(出)已中止(核心转储)

首先注意错误不是内存泄漏,双重释放来自该代码

for (i=0 ; i <N ; i++){
  free(R[i]);
  free(R);
}

必须是必须是

for (i=0 ; i <=N ; i++){
  free(R[i]);
}
free(R);

否则你在第一个循环中释放 R 而不是 在 循环之后

因为从第二个循环开始,R[i] 的值如果未定义并且 free 的行为也未定义,因此您再次调用 free R,这两个原因都与 valgrind 产生的消息兼容。

注意,我还将测试更改为 i&lt;=N,使其与用于进行分配的测试相同,但两者都假设您的数组大小为 N+1(至少),否则您会错过一个 free 产生内存泄漏。

如果代码中分配步骤和空闲步骤不连续,并且即使您无法在给定时间分配内存,空闲步骤也已完成,则必须将代码修改为:

if (R != NULL)
{
  for (i=0 ; i <=N ; i++){
    if (R[i] == NULL) /* allocation failed */
      break;
    free(R[i]);
  }
  free(R);
}

如果 R 为 NULL,则不取消引用,并且不尝试释放未在分配循环中设置的数组条目,因为 (*(R + i) == NULL) 确实打破了循环

【讨论】:

  • 你的假设是正确的,但这似乎不是我的子问题的解决方案
  • @DavidBrawl 为什么?你看到关于尺寸的评论了吗?
  • 还有另一个问题,尽管它不会出现,除非分配阶段部分失败:要么提前返回本身应该释放R 和所有分配的R[0]..R[i],要么提前返回分支应确保后续的 R[i+1]..R[N] 设置为 NULL。
  • @Useless 是的,但是在给定的代码中有一个 return 所以根本没有免费的
  • 啊,你的意思是因为单个失败的分配停止了free 循环。是的,你完全正确 - 我一直关注部分成功的分配本身。
【解决方案2】:

这是我使用 malloc 为 C 中的二维数组分配内存并释放它的代码

另一种方法是使您的矩阵由一些(指向)struct 以flexible array member 结尾的abstract data type 实现。在这种情况下,您的矩阵创建例程会进行 一个 分配(使用 malloc),并且您的矩阵解除例程可以是一个简单的(强制转换)free。不要忘记处理 malloc(3) 的故障(当您想要一个不适合您的计算机的巨大矩阵时可能会发生这种情况)。

详情已在this answer中给出。

当然还要阅读Modern C 和一些C reference website。

恕我直言,C 中不存在二维数组,您可以只拥有一些已知类型的数组。通过阅读一些 C 标准进行检查,例如 n2176。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多