由于 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 中的内存不足导致的分段错误的主要内容,如果未能解决你的问题,请参考以下文章