【问题标题】:Array data type memory allocation数组数据类型内存分配
【发布时间】:2014-11-22 06:00:24
【问题描述】:

我一直在自学如何用 C 编写代码,并且我成功地编写了一个大小适中的程序。我在编译或执行程序时没有遇到问题,但我有点担心有关数组数据类型的内存分配的小细节。

我通过以下方式为数组动态分配内存:

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

这对于构建 nx3 数组非常有效,我很高兴;但是,我从之前的一些问答中了解到,您不仅需要释放数组本身,还需要释放数组中的每个元素。为什么在我的情况下,我不能释放元素?当我这样做时:

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

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

感谢和最好的问候, 迈克

【问题讨论】:

  • 请提供 SSCCE (sscce.org) ...您的问题很可能出在您未向我们展示的代码中...您可能超出了分配内存的范围.或者,也许您在释放内存后使用它。
  • 感谢您的回复。鉴于我正在编写这个程序来分析学术专有数据,我无法提供该程序。它也超过 1000 行,我敢肯定您不想浪费时间进行调查。我主要是好奇,因为我根本没有释放这个内存,它位于一个 while 循环中,运行了数千个数据点,然后在 i=0 处重新开始数千个点。我不明白为什么它没有段错误...
  • 我没有要求你提供程序,我要求你提供SSCCE,这有点相反。 “我不明白为什么它没有段错误......” - 嗯?首先,您没有给出任何期望它发生段错误的理由;其次,段错误永远不会保证 ...很容易让无效程序碰巧不会崩溃。 malloced 区域的损坏通常会在内存被释放时导致段错误,而不是更早。我建议你学习调试器和内存损坏检测工具,如 valgrind。
  • 我明白了。鉴于我对一般编程的业余知识,我将首先听取您的建议并花时间学习调试工具。我还将努力组合一个输入虚拟数据的 SSCCE,这样您就可以使用一些东西了。对于愚蠢的问题,我深表歉意!
  • 无需道歉,特别是因为您的问题并不愚蠢(它只是反映了不正确的假设)。要点应该是您上面用于 malloc 和释放的代码 sn-ps 是正确的,这不是(直接)您的问题......这是您的代码正在做的其他事情,它破坏了 malloc 的簿记,因此在它尝试释放时导致段错误.请确保,如果您分配 3 个双打(例如),您的程序永远不会尝试存储到第四个......这肯定会产生这种行为。

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


【解决方案1】:

这是一个 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 运行时库总是分配大量内存。)

这强烈表明问题不在于内存分配或释放代码,而在于内存被(错误)使用的代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-03
    • 1970-01-01
    • 2014-08-19
    • 1970-01-01
    • 2012-03-23
    • 1970-01-01
    • 2011-12-15
    • 2011-12-27
    相关资源
    最近更新 更多