当我编写以下程序时,它可以正常工作,即位集数组是在 main() 方法之外声明的。
正确工作
#include <iostream>
#include <bitset>
using namespace std;
bitset<5000> set[5000];
int main(){
cout<<"program runs fine"<<endl;
return 0;
}
但是当我在 main 方法中创建它时,出现堆栈溢出异常。谁能详细解释一下这里发生了什么?通常我会在递归方法中看到堆栈溢出异常。那么谁在这里使用堆栈呢?
#include <iostream>
#include <bitset>
using namespace std;
int main(){
bitset<5000> set[5000];
cout<<"program runs fine"<<endl;
return 0;
}
不起作用并抛出堆栈溢出异常
在 main 中声明它就是在“自动存储”(又称堆栈)中声明它。在 main 之外声明它,就是在“静态存储”又名全局数据中声明它。您正在声明 大量数据。
std::bitset<5000>
在我的 VS2013 系统上是 632 字节(可能是从 5000/8 对齐)。您申报了 5000 个。 5000 * 632 = 3 160 000 字节,或大约 3 兆字节。 VS2013 中的默认堆栈大小为 1 MB,这就是您看到溢出的原因。
存储有自动、存储、动态三种。这些内存分别通俗地称为堆栈、静态(在某些情况下,全局)和堆内存:
int static_int;
int main() {
int automatic_int;
static int local_static_int; // also static storage!
int * dynamic_int_ptr = new int;
}
new
分配,并返回指向保存闪亮新数据的某个 blob 的指针。这些变量在调用 new
时构造,并在调用 delete
时销毁。因为当你将数组声明为全局时,内存分配在进程的数据段中,而当你尝试在函数内声明它时,内存分配在堆栈上。由于您分配了大量内存,因此会导致堆栈溢出异常。
编辑:这里是对内存分配的很好的解释。
您正在尝试在程序堆栈上创建 (5000*5000)/8 字节 - 3Megs 数据,这会导致报告的堆栈溢出。您的程序中没有足够的堆栈空间来执行此操作。当您将其创建为全局时,它将插入到您的程序数据段中。