• stack overflow错误分析


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

    #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处的指令,结果出现错误。这就是一次堆栈溢出!

    一般遇到这个问题,有两个常见的情况,

    一个是存在函数的递归调用,另一个是函数中定义了一个较大的数组或者别的变量。

    1、在函数的递归调用中,函数中定义的局部变量所占的空间要直到递归结束才能被释放,这样函数不停的递归,堆栈早晚会被用完,

    解决这一问题的办法是在递归函数中每次动态的分配变量的内存,在使用结束的时候释放内存。

    遇到这种情况更改堆栈的最大空间大小是没有用的,要从代码的优化入手。下面以二维数组的动态分配为例:

    p=new double*[1000]; 
    for (int m=0;m<1000;m++) { 
    p[m]=new double[5000]; 
    } 
    for(int n=0;n<1000;n++) { 
    delete[] p[n]; 
    } 
    delete[] p; 

    2、堆栈的大小只有1M,如果在函数中定义了一个占用内存比较大的变量,那么也会
    导致堆栈溢出。这种情况只需在定义的时候定义为静态变量就行了,因为静态变量是不占用堆栈内存的。如:

    void main()
    { 
    int a[10010010];
    }

    在函数内定义的变量默认auto类型,也就是栈变量,运行时使用的是栈空间,函数结束后自动清理返回内存。这里在函数内定义如此大的一个数组,
    已经超过了单个函数可使用的最大栈空间,所以也会提示stack overflow。解决办法是将其定义为static int型的静态量,这样就不占用栈空间了。

    void main()
    { 
    static int a[10010010];
    }

    3、除此之外还可以通过修改堆栈的最大空间来解决问题,把project设置里的堆栈加大就可以了,
    默认是1M,你可以加大到10M试试具体如下:
    project-> setting-> link: 在category里选择output,在stack的Reserve里输入0x10000000试试。对于遇到这样的问题建
    议从代码方面去解决,不要盲目的依靠修改堆栈空间来解决,毕竟有的问题靠修改空间是解决不了的,如递归中产生stack overflow。

  • 相关阅读:
    织梦后台如何安装
    Java JFrame实现无边框无标题
    SharePoint 2013的100个新功能之网站管理(一)
    cvFindContours之轮廓个数
    RequireJS 入门指南
    RESTFUL Service : based on Jersey
    hdu 1548 A strange lift(优先队列)
    SharePoint 用户配置文件服务
    SharePoint Foundation 搜索-PowerShell
    SharePoint 企业搜索-PowerShell
  • 原文地址:https://www.cnblogs.com/wzxNote/p/5660847.html
Copyright © 2020-2023  润新知