堆栈里的局部变量

在VC里,一个函数里局部变量,特别是静态数组最大长度可以是多少,google过很多帖子,有很多种说法,但好像没有一个来源于比较正式的官方声明,不过大家都有一个共识,就是VC编译器默认会给出1M的栈空间。但是不是就是说一个数组声明的时候不要超过1M就不会使程序发生overflow的异常呢。这两天写了个程序测试一下,证明是局部数组的声明没有一个规定的具体的上限,当然必须小于1M,大小视程序的复杂度而定,我们可以给定一个规则,如果数组空间需要64K以上,最好用new 的方式,如果小于64K,还是可以直接声明的。把测试的过程写下来,备忘,也让这个结论更有说服力一些,呵呵。

1. 用VC7.1 建立一个WTL的基于Dialog 的工程,加一个按钮Crash, 然后写函数CopyString,这个函数里面递归调用自己,每次让栈分配64K的空间。

2. 在CopyString 的开始出设置一个断点,然后F5启动调试

3. 当运行到断点时,进入汇编模式

扫描二维码关注公众号,回复: 10632092 查看本文章

4. 这里会发现,00430D98 有一个call @ILT+1160(__alloca_probe) (41E48Dh)的调用。

5. 跟进到41E48D,原来是_chkstk 函数的调用。那么这个函数什么情况下调用,为什么要调用呢? 于是看看MSDN。

6. 直接跟进到_chkstk 里,看看第一次里面的内容是怎么样

7. 接下来的事情就是用栈可以分配的空间减去函数申请的空间,如果栈空间不足,则报overflow的异常。后面几次的调用栈截图如下,到第16次的时候,栈溢出。

   

    通常,产生Overflow的异常有两种原因:1) 递归过深,导致栈溢出;2)分配空间过大,导致栈溢出。

    所以,如果你的函数处于几十层调用栈的顶端,最好注意函数里所有局部变量的大小之和。

发布了110 篇原创文章 · 获赞 119 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/qq_25814297/article/details/105257530