【问题标题】:C: Array declared inside a function cant exceed ~8MB of memory.C:在函数内声明的数组不能超过约 8MB 的内存。
【发布时间】:2009-10-18 13:43:28
【问题描述】:

我做错了什么? 在 Mac(2GB RAM)上使用 Eclipse 时,我遇到了以下问题:

每当我尝试创建一个超过 8384896 字节的数组时,都会出现分段错误。将执行以下程序:

#include <stdio.h>

main()
{
    double x[1048112];
    printf("sizeof(x) = %li", sizeof(x));
}

输出将是(如预期的那样):

sizeof(x) = 8384896

但是增加 x 中的元素数量或在 main() 中创建额外的变量会导致程序无法执行和段错误。看起来我达到了一些内存限制,我不明白为什么会这样。 如果有人能向我解释这一点,或者为我的问题提供某种解决方案,我将不胜感激。

【问题讨论】:

  • 当我看到这样的问题时,我意识到 Joel 应该将网站命名为“BungeeJumping”。实际上什么都不会改变。

标签: c memory memory-management


【解决方案1】:

这是一个stack overflow,因为堆栈变量过大。

如果你真的需要分配这么大的东西,你可以在堆上使用malloc

double *x = malloc(1048112 * sizeof(double));

请注意,通过此更改,sizeof(x) 不再返回数组的大小,而是返回 double * 的大小。如果您需要知道您的阵列有多大,您需要自行跟踪。

而且,为了完整起见,当你处理完数据后,你需要调用free,否则你会遇到内存泄漏:

free(x);

【讨论】:

  • 嗯,我有点希望他知道,但我还是把它放在那里了。
【解决方案2】:

OS X 上的进程受限,默认为 8MB 堆栈(尝试从命令行运行 ulimit -s)。

一种选择是尝试使用ulimit -s 65536 之类的东西来增加堆栈大小。这应该会影响从当前 shell 会话运行的所有新进程。

更好的选择是在堆上分配数组:

 double *x = (double*)malloc(9999999)

当你完成数组后,不要忘记使用:free(x) 释放它

编辑:试试这个reference 以获取有关如何使用链接器来增加 OS X 上的最大堆栈大小的信息。同样,首选选项只是在堆上分配大型数组。更简单、更便携。

【讨论】:

  • 请注意,'ulimit -H -s' 的输出显示 65536 作为堆栈大小的硬上限;只有根拥有的进程才能将其限制设置为更大的值。
【解决方案3】:

该问题的其他解决方案包括使用静态数组:

 static double x[1234567];

在您的函数中,或在函数外部使用全局变量。如果全局数组被声明为静态,它将在编译它的文件之外不可见。

无论哪种方式,每次调用例程时都不会更新数组,因此每次调用时都不会“重新开始”,而是与以前相同的旧数据。

【讨论】:

  • 我会注意到这会导致他的函数不可重入。
  • 而且不管函数是否运行,它也会消耗恒定的 9.8MB 内存。
【解决方案4】:

是的,你达到了内存限制......具体来说,你是Stack Overflowing。那你该怎么办 ?在堆上分配内存......如下:

double *x=malloc(1048112*sizeof(double));

【讨论】:

    【解决方案5】:

    基于 malloc 的解决方案是正确的,但是这个解决方案可以省去您必须自己跟踪内存的麻烦:

    #include <stdio.h>
    
    static double x[1048112];
    main()
    {
    
        printf("sizeof(x) = %li", sizeof(x));
    }
    

    在函数体之外声明为静态的变量不会从堆栈中分配,它们的可见性仅限于定义它们的文件。

    【讨论】:

      【解决方案6】:

      您可以通过链接器设置增加堆栈上允许的空间量,或者最好开始使用动态内存。

      【讨论】:

      • Futzing 链接器无济于事;这是 MacOS X 上的软 O/S 限制(硬上限默认为 64 MB - 对于非 root 用户)。
      【解决方案7】:

      附带说明:根据我的经验,在某些情况下,这种性质的问题(“为什么我的巨大自动数组会导致崩溃”)源于初学者对数组对象的物理性质的误解。我不止一次遇到坚信数组物理上由一个“指针”组成的人,该指针指向实际元素的附加内存块。他们还认为,自动数组只占用很少量的堆栈内存(用于所谓的“指针”),而大元素块分配在别处,而不是堆栈中。这可能是人们(即使是那些完全意识到堆栈空间的“有限性”的人)认为定义大型自动数组没有问题的可能原因之一。

      【讨论】:

        【解决方案8】:

        只是让您知道 Windows 中的这个限制是 1 mb

        此代码有效

        无效我的函数() { static char yes[1100000]//在堆中分配 }

        此代码不起作用

        无效我的函数() { char yes[1100000]//在栈中分配 }

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-12-05
          • 2015-07-29
          • 2017-03-25
          • 2016-07-12
          • 2015-04-12
          • 1970-01-01
          • 2011-10-11
          • 1970-01-01
          相关资源
          最近更新 更多