stackoverflow出现的原因

栈溢出(stack overflow)

大家知道程序里面的函数是相互调用的,但是它的实现原理知道么?
在这里插入图片描述
这是一段C的代码,在main函数里面调用了add函数,下面是编译之后的汇编语言和机器码。
在这里插入图片描述
在这里插入图片描述
大家可以看到第34行代码是call指令,call指令后面跟着的,是跳转后的程序地址。

我们来看add函数。可以看到,add函数编译之后,代码先执行了一条push指令和一条mov指令;在函数执行结束的时候,又执行了一条pop和一条ret指令。这四条指令的执行,其实就是在进行我们接下来要讲 压栈(Push)和 出栈(Pop)操作。

这里是在原来顺序执行的指令过程里,执行了一个内存地址的跳转指令,让指令从原来顺序执行的过程里跳开,从新的跳转后的位置开始执行。

那我们又如何让跳转后执行完目标函数,返回到调用处那?

1.首相我们可以将调用的代码填充到调用处,如果A函数调用B,B函数代码直接填充到A函数中,这样是没问题的;但是如果A调用B,B也调用A,这下你该如何?显然,这样行不通。
2.我们可以把调用处的地址记录在寄存器里面,但是调用多次,显然,寄存器也不够用了。
上面两个方法肯定走不通,于是科学家想出了在内存里面开辟一段空间,用栈这个 后进先出(LIFO,Last In First Out)的数据结构。

栈就像一个乒乓球桶,每次程序调用函数之前,我们都把调用返回后的地址写在一个乒乓球上,然后塞进这个球桶。这个操作其实就是我们常说的 压栈。如果函数执行完了,我们就从球桶里取出最上面的那个乒乓球,很显然,这就是出栈。拿到出栈的乒乓球,找到上面的地址,把程序跳转过去,就返回到了函数调用后的下一条指令了。
在这里插入图片描述

其实你对JAVA的JVM有一定了解的人,它的方法调用也是和上面的图解一样的。

因为栈的大小固定的,你在不断的压栈,栈的空间肯定会使用完毕,之后再压入,肯定会出现栈溢出(stack overflow),在平常开发中,递归调用中容易出现。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值