c/c++因为数组开得太大导致程序无法正常运行
我发现当我运行一下代码的时候,发现我还没输入数组里的值程序就自动运行结束了。这个原因确实让人很困扰。
`
#include <iostream>`
`using namespace std;`
`int main(){`
`int a[1000][1000];`
`for(int i=0;i<1000;i++)`
`for(int j=0;j<1000;j++)`
`cin>>a[i][j];`
`for(int i=0;i<1000;i++)`
`for(int j=0;j<1000;j++)`
`cout<<a[i][j]<<" ";`
`}
`
然后在网上搜寻了20多分钟终于找到了自己想要的答案:
把数组放在全局变量就OK了:
`#include <iostream>`
`using namespace std;`
`int a[1000][1000]`;
`int main(){`
`for(int i=0;i<1000;i++)`
`for(int j=0;j<1000;j++)`
`cin>>a[i][j];`
`for(int i=0;i<1000;i++)`
`for(int j=0;j<1000;j++)`
`cout<<a[i][j]<<" ";`
`}
`
那么我们该研究研究这个问题所在了。
WHY???
这就涉及到C语言的内存分配问题,C语言的占用内存可以分为5个区域:
代码去(Text Segment):就是存放编译后的代码的二进制机器码
堆区(Heap):用于动态内存分配,一般由程序员分配和释放。如果程序员不释放,结束程序的时候可能有操作系统回收。(malloc—free与new—delete)
栈区(stack):由编译器自动分配和释放,一般存放局部变量、函数参数(!!!)
全局初始化数据区/静态数据区(Data Segment):就是存放全局变量和静态变量的地方,这一块区域被整个进程共享
未初始化数据区(BBS):在运行时改变值。改变值(初始化)的时候,会根据它是全局变量还是局部变量,进到他们该去的区。
在Windows下,Data Segment的所允许的空间大小取决于剩余内存的大小,也就是说,如果电脑剩余8G内存的话,int类型的二维数组甚至可以开到46340*46340的大小;
而Stack的空间只有2M!!也就是210241024=2097152字节,局部变量空间顶多放得下下524288个int类型!
设置的数组是1000*1000的数组的大小就是1000000大于524288肯定不能装得下,就会导致数组的溢出
补充:关于这个BBS区,我们作如下的讨论:
比如说我们新int a[520072];520072个int大概有1.984MB很接近2MB但是我们在新声明变量的时候,不会导致栈溢出。
int a[520072];
int a,b,c,d;
这就是BBS区存在的功劳,在运行时改变值,改变值(初始化)的时候会根据是局部变量该是全部变量把变量放到相应的区域。如果没有改变值,这些变量就在BBS里面与世无争。
在没有初始化之前,这些a b c d就是安安稳稳的呆在BBS里面与世无争。但是在局部变量里面定义数组的时候,数组会自动初始化为0,就被塞进stack区,才会导致栈溢出
int a[520072];
int a=10,b=20,c=30,d=40;
这样就会导致栈溢出