zoukankan      html  css  js  c++  java
  • Stack overflow 编译能通过,运行时出现Stack overflow

    大家都知道,Windows程序的内存机制大概是这样的,全局变量(局部的静态变量本质也属于此范围)存储于堆内存,该段内存较大,一般不会溢出; 函数地址、函数参数、局部变量等信息存储于栈内存,VC6中栈内存默认大小为1M,对于当前日益扩大的程序规模而言,稍有不慎就可能出问题。
    (动态申请的内存即new出来的内存不在栈中)

    即如果函数这样写:
    void test_stack_overflow()
    {
    char* chdata = new[2*1024*1024];
    delete []chdata;
    }
    是不会出现这个错误的,而这样写则不行:
    void test_stack_overflow()
    {
    char chdata[2*1024*1024];
    }
    大多数情况下都会出现内存溢出的错误,不信在vc6中随便做个程序,调用一下这个函数试式。


    出现栈内存溢出的常见原因有2个:
    1> 函数调用层次过深,每调用一次,函数的参数、局部变量等信息就压一次栈。
    2> 局部静态变量体积太大
    第一种情况不太常见,因为很多情况下我们都用其他方法来代替递归调用(反正我是这么做的),所以只要不出现无限制的调用都应该是没有问题的,起码深度几十层我想是没问题的,这个我没试过但我想没有谁会把调用深度作那么多。检查是否是此原因的方法为,在引起溢出的那个函数处设一个断点,然后执行程序使其停在断点处, 然后按下快捷键Alt+7调出call stack窗口,在窗口中可以看到函数调用的层次关系。

    第二种情况比较常见了,我就是犯了这个错误,我在函数里定义了一个局部变量,是一个类对象,该类中有一个大数组,大概是1.5M。

    解决办法大致说来也有两种:
    1> 增加栈内存的数目
    2> 使用堆内存
    增加栈内存方法如下,在vc6种依次选择Project->Setting->Link,在Category中选择output,在Reserve中输入16进制的栈内存大小如:0x10000000,然后点ok就可以了。

    其他编译器也有类似的设置,个人认为这不是一个好办法,有一个致命原因,不知道有没有人遇到过,我把栈内存改大后,与数据库建立不了连接了(ADO方式,Acess数据库),把栈内存还原,问题立刻消失。不知道究竟是什么原因,有知道的可以告诉我。

    第二种解决办法是比较可行的,具体实现由很多种方法可以直接把数组定义改成指针,然后动态申请内存;也可以把局部变量变成全局变量,一个偷懒的办法是直接在定义前边加个static,呵呵,直接变成静态变量(实质就是全局变量)。即可以把上例中的函数这么写:

    void test_stack_overflow()
    {
    static char chdata[2*1024*1024];
    }


    当然,除非万不得已,尽量不要使用这么大的数组,出现这种情况多半说明程序结构有问题。

    ============================

    栈溢出了。栈的默认大小1M,超过就出问题了。
    如果不是函数调用太深,一直不退出,就是栈上变量太大,太多。比如:

    char arr[1024][1024]; //直接耗了1M

    ============================

    VC定义超大数组时,stack OverFlow的解决方法,当然了这里的数组不仅仅是int,char,double等内置类型,还可以是其他的类,如CString,CButton,CMap等。

    stack overflow,堆栈溢出
    VC超大数组Stack Overflow的解决方法


    这次在写一个程序的时候,定义了一个超大的char型数组,元素个数超过3000W个的时候,程序无法调试,提示:Stack Overflow。

    用单步调试试了一下,定义数组的时候没问题,但是在开始对数组赋值的时候,就会弹出一个Stack OverFlow的错误提示,有了程序的错误提示,那就好解决了,在百度上搜索了一下,就找到了解决方法.

    如果是英文版:
    project -> setting -> link -> category 选择 output -> stack allocations 里面的 reserve 填入 0x10000000 然后选OK

    当然了,如果还是不能解决的话,那就要用动态数组了,毕竟动态意味着无穷~~

    vc动态数组实现

    -------------------------------------------

    栈被用作存放局部变量、调用函数前存放返回地址等,vc中每个工程默认栈大小为1m,new分配的空间不在栈(stack)中,在堆(heap)中,因此不会是由于new了不delete造成的。栈溢出可能的原因是:生成了大量局部变量或使用了大的局部数组、递归函数设计不当无出口导致一直调用无法返回。可以修改栈的大小解决这个问题,修改方式如下:
    LINK的/STACK选项 :Project-->settings->link->category选output-->
    /STACK :reserve[,commit]
    reserve:栈总大小
    commit:程序开始时系统提供的实际内存量
    缺省:1M,8K
    参数为0取缺省值
    【reserve :2000000 栈被设置为2M 】

  • 相关阅读:
    Android开发 ViewConfiguration View的配置信息类
    Android 开发 倒计时功能 转载
    Android 开发 关于7.0 FileUriExposedException异常 详解
    Android 开发 实现文本搜索功能
    Android 开发 Activity里获取View的宽度和高度 转载
    Android 开发 存储目录的详解
    Android 开发 Fresco框架点击小图显示全屏大图实现 ZoomableDraweeView
    Android 开发 将window变暗
    Android 开发 DisplayMetrics获取Android设备的屏幕高宽与其他信息
    Android 开发 DP、PX、SP转换详解
  • 原文地址:https://www.cnblogs.com/areliang/p/2495470.html
Copyright © 2011-2022 走看看