C++ Difference between global and non-global arrays (Stackoverflow Exception)
本问题已经有最佳答案,请猛点这里访问。
当我编写以下程序时,它工作正常,即位集数组在main()方法之外声明。
正确工作
1 2 3 4 5 6 7 8 9 10 11 | #include <iostream> #include <bitset> using namespace std; bitset<5000> set[5000]; int main(){ cout<<"program runs fine"<<endl; return 0; } |
但是,当我在主方法中创建堆栈溢出异常时,会得到它。有人能详细解释一下这是怎么回事吗?通常我在递归方法中看到堆栈溢出异常。那么谁在这里使用堆栈呢?
1 2 3 4 5 6 7 8 9 10 11 | #include <iostream> #include <bitset> using namespace std; int main(){ bitset<5000> set[5000]; cout<<"program runs fine"<<endl; return 0; } |
不起作用,引发堆栈溢出异常
在main中声明它就是在"自动存储"中声明它,即堆栈。在主数据之外声明它,就是在"静态存储"中声明它,也称为全局数据。您正在声明大量数据。在我的系统中,使用VS2013的
有三种存储:自动、存储和动态。它们分别被通俗地称为stack、static(在某些情况下是global)和heap memory:
1 2 3 4 5 6 7 | int static_int; int main() { int automatic_int; static int local_static_int; // also static storage! int * dynamic_int_ptr = new int; } |
- 自动存储在编译时/运行时混合分配。堆栈在函数的运行时条目处展开以保存局部变量,但这是一个已知的编译时值,因为变量的数量及其大小是众所周知的(我忽略了这里的动态数组,因为它们是非标准的),这些变量是在作用域条目上构造的,并在作用域退出时销毁。
- 静态存储在编译时分配。这个内存是预先支付的,在程序启动时构建的。它在程序退出时被销毁。
- 动态存储在运行时分配。这个内存由
new 分配,并返回一个指向某个blob的指针,该blob保存了您闪亮的新数据。这些变量在调用new 时构造,在调用delete 时销毁。
因为当您将数组声明为全局时,内存在进程的数据段中分配,而当您试图在函数中声明数组时,内存在堆栈上分配。因为您分配了大量的内存,所以会导致stackoverflow异常。
编辑:这里是关于内存分配的很好的解释。
您正在尝试在程序堆栈上创建(5000*5000)/8个字节-3megs的数据,这会导致报告的堆栈溢出。您的程序中没有足够的堆栈空间用于此操作。将其创建为全局时,它将插入到程序数据段中。