【问题标题】:Segmentation Fault on creating an array in C在 C 中创建数组时出现分段错误
【发布时间】:2011-11-24 09:07:04
【问题描述】:

我最近迁移到了一台新的笔记本电脑 - HP dv6119tx(Intel Core i5,4 GB RAM)。它安装了 Windows 7 Home Premium 64 位。

我正在尝试在 C++(Dev C++)中创建一个长度为 10^6 的 int 类型的数组,我曾经在我的最后一台笔记本电脑(32 位 Windows 7 Ultimate/Ubuntu Linux,2GB RAM)上轻松创建该数组以及我编写的所有其他环境(大约需要 3.5 MB 的 RAM)。但是使用当前设置,我在调试模式下收到“分段错误”错误。

屏幕截图(编辑):
第一个屏幕截图显示 10^5 在当前设置上工作,而 10^6 不在。我的最后一台机器上没有 10^6 的屏幕截图,但我已经用过很多次了。

编辑:
如果我将数组声明为 global 或在堆上动态创建它为

,程序会正常工作
int* a = new int[MAX];  

但我无法理解的是,当本地阵列在堆栈上占用微不足道的 3.5 MB 内存时(并且在 2 GB 机器上运行良好),为什么这个问题会出现在 4GB 机器上?这是用户堆栈空间问题吗?可以手动增加吗?

编辑 2:
我特别问这个问题是因为我在 SPOJ 上提交了许多解决方案,在堆栈上创建了 10^6 大小的数组。以我目前的设置,我觉得无法做到这一点是残废的。我更喜欢堆栈而不是堆,因为它没有内存泄漏问题;和全局变量上的局部变量,因为它们很整洁并且不会弄乱命名空间。

【问题讨论】:

  • 这是回答这个问题的好地方。
  • @RaymondChen:再数一遍,有六个零。
  • 您可以增加堆栈大小,但不能。你只是无缘无故地占用了一堆内存。不要滥用堆栈。将大对象放在堆上。
  • @Raymond 您可以永久删除评论。将光标悬停在评论的最右端(时间之后),您会看到一个小十字出现。
  • 堆栈空间的数量是在链接时设置的,IIRC——此时编译器和链接器等不知道或关心你的代码将在哪台机器上运行,或者它有多少内存已。除非您告诉链接器和/或编译器设置更大的堆栈,否则您将得到默认值。

标签: c++ c arrays segmentation-fault stack-overflow


【解决方案1】:

4 MB 的堆栈相当大。 Windows 上的默认大小为 1MB。您需要使用链接器的/STACK 选项来请求更大的尺寸。

【讨论】:

  • 堆栈的大小受设计限制。您可以增加堆栈大小,但对于如此大的对象,最好找到一种不同的方式来分配它们。
  • 一般来说是的。不过,我现在在我的一个项目中使用了一个手动库,它需要一个 2MB 的堆栈才能正确初始化,因此我的想法是有时这是必要的。
【解决方案2】:

这样创建的数组存储在堆栈中。但是,堆栈的大小非常有限,因此您遇到了堆栈溢出和崩溃。

这样做的方法是在堆上分配:

int *a = (int*)malloc(MAX * sizeof(int));

//  Do what you need to do.

//  Free it when you're done using "a".
free(a);

【讨论】:

  • 谢谢,我刚刚编辑了问题以包含这个观点。您现在可以建议吗?
  • 是的,用户堆栈空间(默认情况下)非常小。当您声明一个本地数组int a[MAX] 时,它被放置在堆栈上。所以一个大数组可能会溢出堆栈。
  • 请注意:VLA 是 C99 功能。此外,这些代码行最终可能会写入它们不应该写入的内存中,甚至会尝试释放一些从未真正存在过的东西,以防 malloc 失败。添加一个 if(a){ ... }。如果是 C,则不需要演员表。
  • @Muggen:同意,虽然它不是 VLA,因为 MAX 是一个常数。此外,这个问题同时被标记为 C 和 C++,所以我给出了一个适用于两者的解决方案。
  • @Mysticial,哎呀,关于宏是正确的。我了解这两个标签的问题。
【解决方案3】:

您可以将缓冲区指定为static,而不是分配内存。例如:

static int a[MAX];

这种方法的优点是您无需跟踪内存分配。

【讨论】:

    猜你喜欢
    • 2013-02-23
    • 1970-01-01
    • 2016-01-07
    • 2012-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多