数组数据类型内存分配

时间:2014-09-27 08:34:53

标签: c arrays pointers segmentation-fault dynamic-memory-allocation

我一直在教自己如何用C语言写作,而且我已经成功地编写了一个大小合适的程序。我没有编译或执行程序的问题,但我有点担心有关阵列数据类型的内存分配的细节。

我以下列方式动态地将内存分配给数组:

double **array=malloc(n*sizeof(*array));
for(i=0; i<n; i++){
    array[i]=malloc(3*sizeof(*(array[i])));
}

这非常适合构建nx3阵列,我很高兴;但是,我从许多以前的Q&amp; A中获得了上下文,你不仅需要释放数组本身,还需要释放数组中的每个元素。为什么,在我的情况下,我不能释放元素?当我这样做时:

for(i=0; i<n; i++){
    free(array[i]);
}
free(array);

循环导致内存损坏。当我删除循环并简单地释放数组时,没有分段错误或损坏,它运行顺利。有人可以向我解释一下吗?我不理解在像这样的实例中释放指针与变量的原理吗?

谢谢和最诚挚的问候, 麦克

1 个答案:

答案 0 :(得分:0)

这是一个MCVE(How to create a Minimal, Complete, and Verifiable Example?)或 SSCCE(Short, Self-Contained, Correct Example) - 同一想法的两个名称和链接 - 非常基于您的代码:

#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运行时库总是进行大量的内存分配。)

这有力地表明问题不在内存分配或释放代码中,而是在使用(错误)内存的代码中。