当我做:
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
vector 在堆上分配内存,而示例中的 myArray 在堆栈上分配内存,这可能导致堆栈溢出。
栈主要用于存放函数参数、返回值等,不宜存放大量数据。这就是为什么它通常具有由操作系统指定的有限大小。
另一方面,堆则完全不同。它可以根据其使用情况“增长”。如果堆用完所有内存,它可能会使用磁盘上的交换空间。所以它可以比堆栈大得多。
在myArray
您尝试120000
在堆栈上分配(从而使其崩溃),而在 上myVect
,您正在堆上进行分配。
您的程序可以使用的堆栈空间量是有限的。如果您在堆上分配数组(使用new
运算符),一切都应该没问题。std::vector
还分配堆上的对象。
数组和std::vector
在 C++ 中是不同的。'Array' 是静态分配的,这意味着它从堆栈中获取内存。但是std::vector
是动态分配的,这意味着它从所谓的“免费存储”或“堆”中获取内存。
这就是为什么你可以有一个大向量但有一个限制大小的数组。
在几乎所有现代 C++ 编译器上,每个双精度数都是 8 个字节长。它们中的一个数组将消耗:
120000 * 8 = 960,000
130000 * 8 = 1,040,000
这意味着程序中每个堆栈帧的大小大约为 1 MB。由于数组(和所有其他“自动变量”)存储在堆栈中,因此每个函数的大小限制为 1 MB。向量和其他对象使用堆内存,这可以为您提供几 GB 的空间。
如果您需要增加堆栈大小,请查看此线程: Change stack size for a C++ application in Linux during compilation with GNU compiler