由于 C 中的内存不足导致的分段错误

Posted

技术标签:

【中文标题】由于 C 中的内存不足导致的分段错误【英文标题】:Segmentation fault due to lack of memory in C 【发布时间】:2011-05-12 09:08:49 【问题描述】:

这段代码给了我大约 1/2 的时间段错误:

int main(int argc, char **argv) 
    float test[2619560];
    int i;
    for(i = 0; i < 2619560; i++)
        test[i] = 1.0f;

我实际上需要分配一个更大的数组,有什么方法可以让操作系统让我获得更多内存吗?

我使用的是 Linux Ubuntu 9.10

【问题讨论】:

【参考方案1】:

您正在溢出默认的最大堆栈大小,即 8 MB。

您可以增加堆栈大小 - 例如。 32 MB:

ulimit -s 32767

...或者您可以使用malloc 切换到分配:

float *test = malloc(2619560 * sizeof test[0]);

【讨论】:

如果您使用 malloc,如果分配成功,您可以检查代码 - 比运行分配并希望它不会崩溃要好得多。 (附录,与其说是评论@caf) @Sam Dufel 请注意,即使您的内存不足,某些系统(例如默认情况下的 linux)也可以从 malloc 返回一个非空指针 - 当您尝试访问时会导致类似的崩溃那段记忆。 可能更准确的说法是,某些系统将分配虚拟地址空间和提交后备存储的概念分开。 根据 malloc 手册页,'Unix98 标准要求 malloc()、calloc() 和 realloc() 在失败时将 errno 设置为 ENOMEM。 Glibc 假设这已经完成(并且这些例程的 glibc 版本会这样做);如果您使用未设置 errno 的私有 malloc 实现,则某些库例程可能会失败,而 errno 中没有原因。'【参考方案2】:

现在您正在堆栈上分配(或至少尝试)2619560*sizeof(float) 字节。至少在大多数典型情况下,堆栈只能使用有限的内存量。您可以尝试将其定义为 static

static float test[2619560];

这会将它从堆栈中取出,因此它通常可以使用任何可用内存。在其他函数中,将某些东西定义为 static 会改变语义,但在 main 的情况下,它几乎没有区别(除了递归 main 的大部分理论上的可能性)。

【讨论】:

递归main,嗯?听起来很有趣。 @You:有时用于IOCCC或代码高尔夫。否则,没有那么多(并且在 C++ 中是不允许的)。【参考方案3】:

不要将这么大的对象放在堆栈上。相反,请考虑通过 malloc() 或其朋友分配将其存储在堆中。

260 万个浮点数并不多,即使在 32 位系统上,地址空间也应该没问题。

如果您需要分配一个非常大的数组,请务必使用 64 位系统(假设您有足够的内存!)。 32 位系统每个进程只能处理大约 3G,即使那样你也不能将其全部分配为单个连续块。

【讨论】:

【参考方案4】:

它是堆栈溢出器。 您最好使用 malloc 函数来获取大于堆栈大小的内存,您可以从“ulimit -s”获取它。

【讨论】:

以上是关于由于 C 中的内存不足导致的分段错误的主要内容,如果未能解决你的问题,请参考以下文章

如何避免由于太多ajax调用而导致浏览器内存不足错误

Cypher 查询删除属性导致 neo4j-shell 中的内存不足错误

IDEA 空间不足导致无法打开排查思路

我由于收集太多图片导致虚拟内存不足

由于堆大小增加,android中的内存不足错误

由于虚拟内存不足,线程无法启动C#