超过120000个元素的数组崩溃

Array crashes with more than 120000 elements

本文关键字:数组 崩溃 元素 120000个 超过      更新时间:2023-10-16

当我这样做时:

vector<double> myVect(120000000, 0);

我可以让向量包含我想要的任意多个元素。然而,当我这样做时:

double myArray[120000];

在我的程序崩溃之前,我被限制在120000-130000个元素之间。是发生了什么奇怪的事情,还是数组真的如此有限?

数组本身不受任何固定大小的限制,但您在自动存储(通常称为"堆栈")中分配的数组受堆栈大小的限制。当您在静态存储中分配大型阵列时,您可以制作更大的阵列。动态分配也是如此:无论可以在不触发内存溢出的情况下分配什么大小的向量,都可以使用new运算符生成相同大小的数组。

例如,您可以在不触发堆栈溢出的情况下执行此操作:

static double myArray[120000000]; // static memory area

或者这个:

double *myArray = new double[120000000]; // dynamic memory area

myArray中,您试图在堆栈上分配120000(从而使其崩溃),而在myVect中,您在堆上进行分配。

程序可以使用的堆栈空间是有限的。如果您在堆上分配数组(使用new运算符),那么一切都应该很好。std::vector还分配堆上的对象。

在几乎所有现代C++编译器上,每个double都有8字节长。他们的阵列将消耗:

120000 * 8 = 960,000 
130000 * 8 = 1,040,000

这意味着程序中每个堆栈帧的大小大约为1MB。由于数组(以及所有其他"自动变量")都存储在堆栈中,因此每个函数只能存储1MB。向量和其他对象使用堆内存,这允许您有几个GB的空间。

如果您需要增加堆栈大小,请查看以下线程:在使用GNU编译器编译期间更改Linux中C++应用程序的堆栈大小

vector在堆上分配内存,而您的示例中的myArray在堆栈上分配内存可能会导致堆栈溢出。

堆栈主要用于存储函数参数、返回值等,不应该存储大量数据。这就是为什么它通常由操作系统指定有限的大小。

另一方面,堆是完全不同的。它可以根据使用情况"增长"。如果堆用完了所有内存,它可能会使用磁盘上的交换空间。所以它可以比堆栈大得多。

数组和std::vector在C++中是不同的。'数组"是静态分配的,这意味着它从堆栈中获取内存。然而,std::vector是动态分配的,这意味着它从所谓的"自由存储"或"堆"中获得内存。

这就是为什么你可以有一个大的向量,但有一个有限大小的数组。