2020-09-19

栈溢出

《一个程序最多能使用多少内存》一文,文中讲到:我们不妨将程序可以使用的这段内存称为「有效内存」。

程序的有效内存还可以再分为多个区域,每个区域都有不同的作用

比如:
代码区、全局数据区、堆区、栈区、动态链接库区等。

栈就是这些内存分区中的一个。那么,栈是用来做什么的呢?

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

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

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

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

栈为什么会溢出

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

这个就像木桶里的水,木桶的容量有限,水满了自然会溢出来。

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

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

当然,我们可以通过设置来更改栈内存大小。

那么,什么情况下才会发生栈溢出呢?

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

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

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

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

总结:栈容易溢出是因为栈内存有限,一般就几兆。

原文链接

在原文评论区还有个缓冲区溢出攻击的评论,很有意思,先记一下,完事再去考察准确性。
函数中的变量都是在栈空间,当输入的变量值太大,超过给变量赋予的大小,这时候就会把这个栈空间的一些指令给覆盖掉,比如覆盖到返回地址。然后覆盖返回地址的为jmp之类的跳转指令,然后jmp跳到后面你写的恶意代码指令,就造成了缓冲区溢出攻击

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值