堆栈溢出怎么解决方式

嵌入式操作系统

57人已加入

描述

        堆栈

  堆栈是一个在计算机科学中经常使用的抽象数据类型。堆栈中的物体具有一个特性: 最后一个放入堆栈中的物体总是被最先拿出来, 这个特性通常称为后进先出(LIFO)队列。 堆栈中定义了一些操作。 两个最重要的是PUSH和POP。 PUSH操作在堆栈的顶部加入一 个元素。POP操作相反, 在堆栈顶部移去一个元素, 并将堆栈的大小减一。

         堆栈溢出

  堆栈溢出的产生是由于过多的函数调用,导致调用堆栈无法容纳这些调用的返回地址,一般在递归中产生。堆栈溢出很可能由无限递归(Infinite recursion)产生,但也可能仅仅是过多的堆栈层级。

  堆栈溢出就是不顾堆栈中分配的局部数据块大小,向该数据块写入了过多的数据,导致数据越界,结果覆盖了别的数据。 可以理解为 在长字符串中嵌入一段代码,并将过程的返回地址覆盖为这段代码的地址,这样当过程返回时,程序就转而开始执行这段自编的代码了。

       比如如下这段程序:

  #include《stdio.h》

  int main()

  {

  char name[8];

  printf(“Please type your name:”);

  gets(name);

  printf(“Hello.%s!”,name);

  return 0;

  }

  编译并且执行,输入ipxodiAAAAAAAAAAAAAAAA,执行完gets(name)之后,堆栈如下:

  内存底部 内存顶部

  name EBP ret

  《-------[ipxodiAA][AAAA][AAAA]。。。。。。。。。。。。

  ^&name

  堆栈顶部 堆栈底部

  由于我们输入的name字符串太长,name数组容纳不下,只好向内存顶部继续写‘A’,如果提前申请动态内存就可以避免堆栈溢出。而此例由于堆栈的生长方向与内存的生长方向相反,这些‘A’覆盖了堆栈的老的元素。’EBP ret’都被‘A’覆盖了。在main返回的时候,就会把‘AAAA’的ASCII码:0x41414141作为返回地址,CPU会试图执行0x41414141处的指令,结果出现错误。这就是一次堆栈溢出!

  VS 堆栈溢出的解决方案

  方法一 : 不静态分配,用new动态创建,从堆中分配的,堆的空间足够大。

  不过记得写析构函数,delete你申请的堆空间。其实这样也挺方便,类结束的时候会自动调用析构函数释放空间。养成“不在栈上定义大数组/大对象”的好习惯很重要,否则再大的栈也会被撑爆的。

  当然,如果你不喜欢new,delete的话,还是静态分配(毕竟静态分配有很多好处),那么可以通过改变默认栈空间来解决。

  方法二 :STACKSIZE 定义.def文件

  语法:STACKSIZE reserve[,commit]

  reserve:栈的大小;commit:可选项,与操作系统有关,在NT上只一次分配物理内存的大小

  方法三 :设定Visual Stdio 的/STACK 大小

  1 VC6.0修改:

  打开工程,依次操作菜单如下:Project-》Setting-》Link,在Category 中选中Output,然后在Reserve中设定堆栈的最大值和commit。

  注意:reserve默认值为1MB,最小值为4Byte;commit是保留在虚拟内存的页文件里面,它设置的较大会使栈开辟较大的值,可能增加内存的开销和启动时间。

  2 VS2008修改

  在 Visual Studio 开发环境中设置此链接器Linker选项

  · 右键打开项目的“属性页”对话框。有关详细信息,请参见设置 Visual C++ 项目属性。

  · 单击“链接器Linker”文件夹。

  · 单击“系统 System”属性页。

  · 修改下列任意一个(都该也可以)属性:

  · 堆栈提交大小Stack Reserve Size 100000000;

  · 堆栈保留大小Stack Commit Size 100000000.

  堆栈

  在平常的上网当中是否遇到过电脑弹出网页消息提示“堆栈溢出”,那么现在小编就简单描述下解决这个问题的办法。

 堆栈

  打开自己常用的浏览器,这个方法适用于所有的浏览器。所以不用担心会出现其他的状况。

  堆栈

  找到菜单栏,在菜单栏上面存在一个“工具”选项,单击工具这个按钮。

  堆栈

  在“工具”这个选项下面有个“Internet选项”,点击这个功能选项。就可以进入“Internet选项”界面。

 堆栈

  主要的操作就在“Internet选项”里面,当你点击“Internet选项”的时候就会弹出一个窗口。

 堆栈

  在“Internet选项”窗口上方有个“高级”按钮,点击这个按钮,然后在“设置”下一级存在一个功能“禁用脚本调试”,这个功能项在默认状态下是勾选起的,现在我们要取消勾选这个功能项。

 堆栈

  完成了这最后一步就解决了堆栈溢出的问题,现在就可以马上试试,是不是不会出现了呢?

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分