C ++全局和非全局数组之间的差异(Stackoverflow异常)

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;
}

不起作用,引发堆栈溢出异常enter image description here


在main中声明它就是在"自动存储"中声明它,即堆栈。在主数据之外声明它,就是在"静态存储"中声明它,也称为全局数据。您正在声明大量数据。在我的系统中,使用VS2013的std::bitset<5000>是632字节(可能是5000/8的对齐)。你要申报5000张。5000*632=3 160 000字节,或大约3兆字节。在VS2013中,堆栈的默认值是1兆字节,这就是您看到溢出的原因。

有三种存储:自动、存储和动态。它们分别被通俗地称为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的数据,这会导致报告的堆栈溢出。您的程序中没有足够的堆栈空间用于此操作。将其创建为全局时,它将插入到程序数据段中。