大阵列尺寸上的分段错误


116

以下代码在2Gb机器上运行但在4GB机器上运行时出现分段错误。

int main()
{
   int c[1000000];
   cout << "done\n";
   return 0;
}

阵列的大小仅为4Mb。在c ++中可以使用的数组大小是否有限制?

Answers:


130

您可能在这里只是堆栈溢出。数组太大,无法放入程序的堆栈地址空间。

如果您在堆上分配数组,则应假定计算机有足够的内存,这应该没问题。

int* array = new int[1000000];

但是请记住,这将需要您进入delete[]阵列。更好的解决方案是使用std::vector<int>它并将其大小调整为1000000个元素。


3
感谢您的回答,但是您能否解释一下为什么数组在堆栈上分配,为什么不在主程序内存中分配。
Mayank

18
给定的代码在堆栈上分配,因为在编译时它被指定为具有恒定数量元素的数组。值只放在堆使用malloc,新等
塞斯·约翰逊

6
所有自动变量都分配在堆栈上。如果您看不清楚的话,您会看到从堆栈指针中减去了局部变量的大小。当您调用malloc或calloc或任何内存功能时,该功能会找到足够大的内存块来满足您的要求。
重新播放

@Charles为什么我们可以从堆而不是从堆栈分配更多的内存?据我了解,堆栈和堆在内存中分配的地址空间中都朝相反的方向移动。
saurabh agarwal 2015年

2
@saurabhagarwal堆不动。它甚至不是连续的内存区域。分配器仅返回符合您的大小要求的可用内存块,堆栈和堆在哪里?
phuclv 2015年

56

在C或C ++中,通常将本地对象分配在堆栈上。您在堆栈上分配了一个大数组,超出了堆栈的处理能力,因此您得到了一个 stackoverflow。

不要在堆栈上本地分配它,而是使用其他位置。这可以通过使对象成为全局对象或在全局堆上分配它来实现。如果不使用任何其他编译单元的,则全局变量很好。为确保这不会偶然发生,请添加静态存储说明符,否则只需使用堆即可。

这将在BSS段中分配,该段是堆的一部分:

static int c[1000000];
int main()
{
   cout << "done\n";
   return 0;
}

这将在DATA段中分配,它也是堆的一部分:

int c[1000000] = {};
int main()
{
   cout << "done\n";
   return 0;
}

这将分配在堆中某个未指定的位置:

int main()
{
   int* c = new int[1000000];
   cout << "done\n";
   return 0;
}

如果您使用第三个模式在堆上分配内存,请不要忘记在某个阶段删除delete []指针,否则会泄漏内存。或研究智能指针。
大卫2012年

8
@meowsqueak当然,对delete您分配的每个地方来说,这都是一个好习惯new。但是,如果您确定只分配一次内存(就像在main中一样),则绝对不需要-内存即使在没有exit的情况下也可以在main的出口处释放delete
冈瑟·皮埃兹

'at'drhirsch(无论如何,您如何做一个角色?)-是的,很公平。由于OP对这种语言来说是陌生的,所以我只是想确保他们以及其他看到您的好答案的人都知道,如果通常使用第三种选择的含义。
davidA 2012年

15

另外,如果您在大多数UNIX&Linux系统上运行,则可以通过以下命令临时增加堆栈大小:

ulimit -s unlimited

但是要小心,内存是有限的资源,强大的功能会带来很大的责任:)


1
这是解决方案,但是我建议所有人在删除该程序堆栈大小的默认限制时都应格外谨慎。您不仅会遇到严重的性能下降,而且系统可能会崩溃。例如,我试图在具有4GB RAM的计算机上使用quicksort对具有16000000个整数的数组进行排序,而我的系统几乎被杀死。大声笑
rbaleksandar 2014年

@rbaleksandar我认为您〜16MB的程序几乎会杀死您的计算机,因为您正在使用该阵列的多个副本(可能每个函数调用一个副本?)尝试一种更具内存意识的实现;)
RSFalcon7 2014年

我很确定数组处理是可以的,因为我是按引用而不是按值传递的。Bubblesort也会发生相同的情况。即使我的quicksort实现很烂,您也无法正确实现。大声笑
rbaleksandar 2014年

大声笑你可以尝试基数排序,或简单地使用std :: sort :)
RSFalcon7 2014年

1
没有机会。这是实验任务。:D
rbaleksandar 2014年

3

您的数组正在堆栈中分配,在这种情况下,尝试使用alloc分配大小相同的数组。


3

因为您将数组存储在堆栈中。您应该将其存储在堆中。请参阅此链接以了解堆和堆栈的概念。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.