什么是stack overflow

已举报 回答 关注
什么是stack overflow
问在线客服
扫码问在线客服
  • 回答数

    8

  • 浏览数

    5,905

8个回答 默认排序
  • 默认排序
  • 按时间排序

已采纳
顾名思义,stack overflow 就是是栈溢出了。在进行数值运算时,我们常常要和运算结果的溢出打交道。数值运算结果可能上溢(overflow),也可能是下溢(underflow)。不过栈的溢出显然只可能是上溢,即栈空间被用完了。在提起“栈”(stack)这个概念的时候,千万不要忘记了它的兄弟“堆”(heap),也要切记不要把二者搞混了。
那么,什么时候会把给用完了呢?如果我们记得C程序中的局部变量是在栈中分配的,函数调用会占用一部分栈空间,则可以很容易地构造出相应的测试用例。

1、定义占用空间过大的局部变量所导致的栈溢出

C:\ more stack_local.c

/*
* Allocate too much memory from stack will cause stack overflow.
*/

#include stdio.h

int main(int argc, char *argv[])
{
int foo[1000000];
return 0;
}

C:\ cl stack_local.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.

stack_local.c
Microsoft (R) Incremental Linker Version 8.00.50727.42
Copyright (C) Microsoft Corporation. All rights reserved.

/out:stack_local.exe
stack_local.obj

C:\ stack_local

此时出现一个异常对话框:stack-local.jpg 。

2、函数递归调用导致的栈溢出

C:\ more stack_recursive.c

/*
* Infinite recursive calls will lead to stack overflow soon.
*/

#include stdio.h

static void foo(void);
static void bar(void);

int main(int argc, char *argv[])
{
foo();
return 0;
}

static void foo(void)
{
bar();
}

static void bar(void)
{
foo();
}

C:\ cl stack_recursive.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.

stack_recursive.c
Microsoft (R) Incremental Linker Version 8.00.50727.42
Copyright (C) Microsoft Corporation. All rights reserved.

/out:stack_recursive.exe
stack_recursive.obj

C:\ stack_recursive

该程序没声没息就结束了。查看进程返回值能发现它其实是异常终止了。只不过没有像 stack_local 那样弹出一个对话框。

C:\ echo %errorlevel%
-1073741819

要搞清楚这两个程序为什么有这点细微的区别,可以查阅一下二者的汇编代码。原来是 _chkstk() 在起作用,其中 stack_local 在程序初始加载时就会导致 _chkstk() 失败,触发异常。而 stack_recursive 可以正确加载,并运行一段时间,然后导致栈溢出,并触发异常。

要正确处理栈溢出采用以下办法:
(1)修正我们的程序,不要造成无穷递归或太深的递归。我们可以把某些递归代码非递归化,例如那个经典的 qsort ,最好就用非递归的算法来实现,就比较皮实一点。
(2)修正我们的程序,不要定义过大的局部变量,特别是在定义大结构、大数组时要格外小心。有时我们可能会用 _alloca() 这样的特殊函数直接在栈上分配空间,更要多加注意。
(3)利用编译器的特性,将进程允许的栈大小设置得大一些。例如可以采用 MSC 中的 /STACK 参数开关。
(4)对于那些还可能导致栈溢出的代码,采用 Microsoft 的结构化异常处理或标准的 C++ 异常处理机制,结合 _resetstkoflw() 进行处理。当然了,要是不嫌麻烦,我们也可以自己探测所用栈的大小,动态地检测是否可能导致栈溢出,以避免可能的异常。
取消 评论
将那个“stack overflow at line: 355”的小框移到大网页右上端,使小框交叉按钮与大网页交叉按钮重叠一部分,先按下小框交叉按钮,再快速按下大网页交叉按钮,然后一切搞定!!!! 特别好用
取消 评论
Stack Overflow是一个与程序相关的IT技术问答网站。用户可以在网站免费提交问题,浏览问题,索引相关内容,在创建主页的时候使用简单的HTML。在问题页面,我们不会弹出任何广告,销售信息,JavaScript 窗口等。 Stack Overflow 由 Joel Spolsky
取消 评论
刷新...如果几次下来还是不行的话...你去看看有上面插件你是没有装的..土豆网的主要是飞速土豆和i土豆... 优酷么...飞速土豆也可以用的...一般只要是网上的视频,飞速土豆都能用的... 还有,可能是你哪里的网速过慢...
取消 评论
你的堆栈溢出了!重装吧,方便快捷!
取消 评论
权限问题吧
取消 评论
电脑不能识别那种格式。
取消 评论
造成了堆栈的益出,在IE的【Internet选项】的【高级】里禁用脚本调试,

试试 开始...运行,入REGSVR32 URLMON.DLL,回车后重启系统,

然后进入IE的“工具”→“Internet选项”→ “程序”,

单击“重置Web设置”按纽就行啦
取消 评论
ZOL问答 > 什么是stack overflow

举报

感谢您为社区的和谐贡献力量请选择举报类型

举报成功

经过核实后将会做出处理
感谢您为社区和谐做出贡献

扫码参与新品0元试用
晒单、顶楼豪礼等你拿

扫一扫,关注我们
提示

确定要取消此次报名,退出该活动?