C++全局数组和非全局数组的区别(Stackoverflow异常)[duplicate]

ego6inou  于 5个月前  发布在  其他
关注(0)|答案(3)|浏览(69)

此问题在此处已有答案

Segmentation fault on large array sizes(7个答案)
5年前关闭。
当我写下面的程序时,它工作正常,即位集数组在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;
}

不工作并抛出堆栈溢出异常

khbbv19g

khbbv19g1#

在main中声明它就是在“自动存储”中声明它,也就是在堆栈中声明它。在main之外声明它,在“静态存储”AKA全局数据中声明它。您正在声明 * 大量数据。* std::bitset<5000>在我的VS 2013系统上为632字节(可能是5000/8的对齐)。你声明了5000个。5000 * 632 = 3160000字节,或者大约3 MB。在VS 2013中,堆栈的默认值是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的指针,该blob保存着你的闪亮的新数据。这些变量在new被调用时被构造,在delete被调用时被析构。
gr8qqesn

gr8qqesn2#

因为当你声明数组为全局时,内存是在进程的数据段中分配的,而当你试图在函数内部声明它时,内存是在堆栈上分配的。由于你分配的内存量很大,这会导致堆栈溢出异常。
编辑:Here是内存分配的一个很好的解释。

bvn4nwqk

bvn4nwqk3#

您正在尝试在程序堆栈上创建(5000*5000)/8字节-3兆的数据,这导致报告的堆栈溢出。您的程序中没有足够的堆栈空间用于此操作。当您将其创建为全局时,它会插入到程序数据段中。

相关问题