C中的双重自由或腐败3d数组

时间:2015-02-04 08:48:09

标签: c arrays malloc free corruption

我在释放3d数组时遇到“双重释放或损坏”错误。任何人都可以告诉我代码中的问题在哪里? 数组的大小为2 * N * N.这里N的值是100.即使没有铸造,也是相同的结果。 这是代码:

// Mallocing 
double ***h = malloc(2 * (sizeof(double**)));
for(i = 0; i < N; i++) {
    h[i] = malloc(N * sizeof(double*));
    for(j = 0; j < N; j++) {
        h[i][j] = malloc(N * sizeof(double));
    }
}

// Freeing
for(i = 0; i < N; i++) {
    for(j = 0; j < N; j++) {
        free(h[i][j]);
    }
    free(h[i]);
}
free(h);

该程序运行正常,但最后我得到一个错误'双免费或腐败(!prev):0x08cd24f8' 中止(核心倾倒)。

5 个答案:

答案 0 :(得分:2)

对于第一个维度,您分配了2个元素:

double ***h = (double***) malloc(2 * (sizeof(double**)));

但您将其视为具有N元素:

for(i = 0; i < N; i++) {
    h[i] = ...

将分配的最外层循环比较更改为:

for(i = 0; i < 2; i++) {

也不要投放malloc的返回值。此外,您的代码缺少错误处理,如果分配失败,则会中断。

答案 1 :(得分:1)

我可以看到你分配2个项目,然后填写其中的N个。

double ***h = (double***) malloc(2 * (sizeof(double**)));
for(i = 0; i < N; i++) {
    h[i] = (double**) malloc(N * sizeof(double*));
    ....
    ....
}

如果N&gt; 2 ...

,您将覆盖未分配的空间

答案 2 :(得分:0)

问题出在这里:

double ***h = (double***) malloc(2 * (sizeof(double**)));
for(i = 0; i < N; i++) {
    // ...
}

您只有malloc 2个元素,并在N上进行迭代。 我想你想要一个大小为N*N*N的数组,但最后却得到了2*N*N

所以这个:

double ***h = (double***) malloc(2 * (sizeof(double**)));

应该是:

double ***h = (double***) malloc(N * (sizeof(double**)));

答案 3 :(得分:0)

如果你的评论中有N = 100的值,那么你需要分配内存来保存N指针指向你只有2的位置。

double ***h =  malloc(N * (sizeof(double*)));

不要投射malloc()

答案 4 :(得分:0)

正如其他人所指出的那样,导致该错误的具体问题是您使用2个元素处理维度,就好像它有N个元素一样。

然而,其核心原因是混淆。我强烈建议您遵循一些规则:

  • 始终将多维数组分配为在相邻内存中分配的真实数组Reference
  • 永远不要将多维数组分配为基于指针的查找表,这些查找表在整个堆中被分段。它们不仅速度慢,而且使代码难以阅读,它们实际上并不是数组。您不能将它们与memcpy()等一起使用。

    不幸的是,有无数糟糕的C编程教师和坏书推介碎片指针到指针查找表。很多程序员都不得不忘记这一点,这太可怕了......

  • 永远不要在程序中使用两个以上的间接级别。永远不应该有这样做的理由,它所做的就是让你的程序不那么可读(参考MISRA-C:2012规则18.5)。这实际上被称为“三星级节目”,并不是一个讨人喜欢的术语。

  • 永远不会转换malloc的结果,因为it is pointless to do so

应该做什么:

double (*array)[Y][Z] = malloc( sizeof(double[X][Y][Z]) );
...
free(array);

示例:

#include <stdio.h>
#include <stdlib.h>

#define X 2
#define Y 3
#define Z 4

int main (void)
{
  double (*array)[Y][Z] = malloc( sizeof(double[X][Y][Z]) );

  double count = 0.0;
  for(int x=0; x<X; x++)
  {
    for(int y=0; y<Y; y++)
    {
      for(int z=0; z<Z; z++)
      {
        array[x][y][z] = count++;
        printf("%f ", array[x][y][z]);
      }
      printf("\n");
    }
    printf("\n");
  }

  free(array);

  return 0;
}

要编译它,您需要一个不超过16年的编译器。