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

在释放3d数组时,我遇到了“双重释放或损坏”错误。 任何人都可以告诉我代码中的问题在哪里? arrays的大小为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’中止(核心转储)。

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

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

但你把它看作是有N元素:

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

在分配时更改最外层循环比较释放到:

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

也不要转换malloc返回值。 此外,您的代码缺少error handling,并且如果分配失败将中断。

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

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

如果N> 2,则覆盖未分配的空间...

问题出在这里:

 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**))); 

如果你的注释中N = 100的值那么你需要分配内存来保存N指针到指针只有2。

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

不要投射malloc()

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

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

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

    不幸的是,有无数糟糕的C编程教师和坏书推介碎片指针到指针查找表。 这么多程序员不得不忘掉这一点,这很吓人……

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

  • 永远不要施放malloc的结果,因为这样做是没有意义的 。

该做什么:

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

例:

 #include  #include  #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 

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