天天看点

c++ 栈溢出简介

一、栈是用来做什么的呢?

    整个内存都是用来存储数据的,栈也不例外。栈用来存储程序的局部数据。

    对于C/C++来说,局部数据是指在函数内部定义的数据,例如在函数内部定义的变量、指针、参数、结构体、数组、对象、引用等,它们都要保存到栈中。

    与之相对应的,在函数外部定义的变量、指针、对象、结构体、数组等都是全局数据,它们要保存到全局数据区。

    而 malloc( )、new、new[ ] 是在程序运行的过程中动态地分配内存,这些内存都位于堆区。

二、栈为什么会溢出

    对每个程序来说,栈能使用的内存是有限的,一般是 1M~8M,这在编译时就已经决定了,程序运行期间不能再改变。如果程序使用的栈内存超出最大值,

    就会发生栈溢出(Stack Overflow)错误,程序就崩溃了。这个就像木桶里的水,木桶的容量有限,水满了自然会溢出来。

三、那么,栈内存一般有多大呢?

    栈内存的大小和编译器有关,编译器会为栈内存指定一个最大值:

四、我们可以通过设置来更改栈内存大小。

五、栈溢出产生场景

    1、

    最常见的就是递归。每次递归就相当于调用一个函数,函数每次被调用时都会将局部数据(在函数内部定义的变量、参数、数组、对象等)放入栈中。

    递归1000次,就会将1000份这样的数据放入栈中。这些数据占用的内存直到整个递归结束才会被释放,在递归过程中只会累加,不会释放。

    如果递归次数过多,并且局部数据也多,那么会使用大量的栈内存,很容易就导致栈溢出了。

    在函数内部定义超大数组也会导致栈溢出,例如定义一个 1024 * 1024 的 int 类型的二维数组,就需要 4M 的内存,这在 VS/VC 下就会发生栈溢出。

    2、定义变量过多

    比如下面这段代码,我就是在vs2015里面运行后程序崩溃的

void TestStack()
{
  int a[1024 * 1024*4];

}      

六、避免方式

    1、增加栈内存:在项目->属性​->链接->系统中增​大栈大小

    2、使用堆内存

    3、用vector替换数组

总结