我一直在自学如何用C编写程序,并成功地编写了一个大小适中的程序。我在编译或执行程序时没有遇到问题,但我有点担心数组数据类型的内存分配方面的一些小细节。
我以以下方式将内存动态分配给数组:
double **array=malloc(n*sizeof(*array));
for(i=0; i<n; i++){
array[i]=malloc(3*sizeof(*(array[i])));
}
这对于构建nx3阵列非常有效,我对此感到高兴;然而,我已经从以前的一些问答中获得了上下文;A不仅需要释放数组本身,还需要释放数组中的每个元素。为什么在我的情况下,我不能释放元素呢?当我这样做时:
for(i=0; i<n; i++){
free(array[i]);
}
free(array);
循环导致内存损坏。当我移除循环并简单地释放数组时,没有分段错误或损坏,并且运行平稳。有人能给我解释一下吗?在这种情况下,我是否不理解释放指针与变量的原理?
谢谢并致以最良好的问候,Mike
这里有一个MCVE(如何创建最小、完整和可验证的示例?)SSCCE(简短、自包含、正确的示例)——同一想法的两个名称和链接——非常紧密地基于您的代码:
#include <stdlib.h>
int main(void)
{
int i;
int n = 20;
double **array = malloc(n * sizeof(*array));
for (i = 0; i < n; i++)
{
array[i] = malloc(3 * sizeof(*(array[i])));
}
for (int x = 0; x < n; x++)
for (int y = 0; y < 3; y++)
array[x][y] = 0.0;
for (i = 0; i < n; i++)
{
free(array[i]);
}
free(array);
return 0;
}
当在Mac OS X 10.9.5上使用GCC 4.9.1编译并在valgrind
3.10.0下运行时,它会产生一个干净的健康状况:
==7957== Memcheck, a memory error detector
==7957== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==7957== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==7957== Command: mma
==7957==
==7957==
==7957== HEAP SUMMARY:
==7957== in use at exit: 25,245 bytes in 373 blocks
==7957== total heap usage: 470 allocs, 97 frees, 31,829 bytes allocated
==7957==
==7957== LEAK SUMMARY:
==7957== definitely lost: 0 bytes in 0 blocks
==7957== indirectly lost: 0 bytes in 0 blocks
==7957== possibly lost: 0 bytes in 0 blocks
==7957== still reachable: 0 bytes in 0 blocks
==7957== suppressed: 25,245 bytes in 373 blocks
==7957==
==7957== For counts of detected and suppressed errors, rerun with: -v
==7957== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
(Mac OS X运行库总是会进行大量内存分配。)
这强烈表明,问题不在于内存分配或释放代码,而在于内存被(错误)使用的代码。