C++堆栈数组限制

C++ stack array limit?

本文关键字:数组 堆栈 C++      更新时间:2023-10-16

我正在运行一些代码,这些代码可能表明我不太理解堆和堆栈之间的区别。下面我有一些示例代码,其中我在堆栈或1234567元素堆上声明一个数组。两者都有效。

int main(int argc, char** argv){
int N = 1234567;
int A[N];
//int* A = new int[N];
}

但是,如果我们将N设为12345678,那么我会得到int a[N]的seg错误,而堆声明仍然可以正常工作。(如果这很重要的话,我使用g++O3-std=c++0x)。这是什么疯狂?堆栈是否有(相当小的)数组大小限制?

这是因为堆栈的大小比堆小得多。堆可以占用程序可用的所有内存。默认情况下,VC++编译的堆栈大小为1MB。该堆栈提供了更好的性能,但适用于较小数量的数据。一般来说,它不用于大型数据结构。这就是为什么在c++中接受列表/数组/字典/ect的函数通常使用指向该结构的指针或引用。通过值传递的参数被复制到堆栈上,传递这样的结构经常会导致程序崩溃。

在您使用N int的示例中,int是4个字节。这使得A[N]~4.7MB的大小比堆栈的大小大得多。

堆随着malloc和co的分配而动态增长。堆栈随着程序运行过程中的每个函数调用而增长。返回地址、自变量和局部变量通常存储在堆栈中(除了在某些处理器体系结构中,其中少数存储在寄存器中)。动态分配堆栈空间也是可能的(但并不常见)。

堆和堆栈竞争使用相同的内存。你可以思考一个从左到右增长,另一个从右到左增长。如果不加以控制,它们可能会发生碰撞。堆栈通常被限制生长超过某个界限。这相对较小,因为预计大多数调用只使用几个字节,并且只使用几个堆栈级别。这个限制很小,但对于大多数任务来说已经足够了。您可以通过更改构建设置(但不适用于Linux ELF二进制文件)或调用setrlimit来扩展此限制。操作系统也可能会施加一个您可以更改的限制。可能存在软限制和硬限制(http://www.nics.tennessee.edu/node/327)。

更详细地了解这些限制超出了问题的范围。底线是堆栈是有限的,而且它很小,因为它与堆竞争实际内存,而对于典型的应用程序,它不需要更大。

http://en.wikipedia.org/wiki/Call_stack