栈溢出(stackoverflow)的原因及解决办法

大家都知道,Windows程序的内存机制大概是这样的:全局变量(局部的静态变量本质也属于此范围)存储于堆内存,该段内存较大,一般不会溢出;

函数地址、函数参数、局部变量等信息存储于栈内存,VC++6中栈内存默认大小为1M,对于当前日益扩大的程序规模而言,稍有不慎就可能出问题(动态申请的内存即new出来的内存不在栈中),即如果函数这样写:

void test_stack_overflow()

{

char *pdata = new[2 * 1024 * 1024];

delete[]pdata;

}

是不会出现这个错误的,而这样写则不行:

void test_stack_overflow()

{

char chdata[2 * 1024 * 1024];

}

大多数情况下都会出现内存溢出的错误,不信在VC++6中随便做个程序,调用一下这个函数试式。

出现栈内存溢出的常见原因有2个:

1>函数调用层次过深,每调用一次,函数的参数、局部变量等信息就压一次栈。

2>局部静态变量体积太大

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

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

解决办法大致说来也有两种:

1>增加栈内存的数目

2>使用堆内存增加栈内存

第一种解决办法:在VC++6种依次选择Project->Setting->Link,在Category中选择output,在Reserved中输入16进制的栈内存大小如:0x10000000,然后点ok就可以了。

其他编译器也有类似的设置,个人认为这不是一个好办法,有一个致命原因,不知道有没有人遇到过,我把栈内存改大后,与数据库建立不了连接了(ADO方式,Acess数据库),还有遇到调用CreateThread会提示栈不够而创建线程失败,把栈内存还原,问题立刻消失。

不知道究竟是什么原因,有知道的可以告诉我。

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

void test_stack_overflow()

{

static char chdata[2 * 1024 * 1024];

}

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

[转]C++ 堆栈溢出的原因以及可行的解决方法的更多相关文章

  1. 今天发现猎豹浏览器的一个大坑 Request.IsAuthenticated 一直为 false;另外附加原因以及临时的解决方法

    今天掉到了一个大坑里面,爬了1个多小时才发现不是代码的问题,居然是浏览器的问题… 下面是问题的发生过程 单点登陆  有2个站点  http://a.abc.com  http://b.abc.com ...

  2. 使用sklearn中的fetch_mldata的错误情况以及可能可行的解决方法

    使用sklearn中的fetch_mldata的错误情况以及可能可行的解决方法 在notebook使用的时候出现了报错 from sklearn.datasets import fetch_mldat ...

  3. silverlight 进行本地串口调用的一种可行的解决方法

    silverlight 是一个很不错的开发平台,我们可以设计出很绚丽的界面,用户可以拥有很好的体验,但是就目前来说,进行本地串口的直接调用时不行的,因为安全的原因,有没有相对简单的调用方式呢? 答案是 ...

  4. html乱码原因与网页乱码解决方法

    造成html网页乱码原因主要是html源代码内中文字内容与html编码不同造成.但无论是哪种情况造成乱码在网页开始时候都需要设置网页编码. charset编码设置 html网页乱码效果截图 一.乱码造 ...

  5. silverlight 进行本地串口调用的一种可行的解决方法 之silverlight端代码

    接上边的文章. 在javascript暴露操作activex 串口接收之后,就是silverlight端进行串口数据的显示,我们的显示方式比较简单,只是为了演示,我们每隔1秒进行数据的获取并显示, 为 ...

  6. 【转】Latex编译报错后中断编译并改正,然后重复出现不明原因报错的解决方法

    转自:https://www.douban.com/note/419828344/ 目录: 一.问题描述 二.测试情况(可以跳过,直接看建议) 三.建议 四.参考资料 正文: 问题描述: 错漏某个符号 ...

  7. XAMPP中Apache因为端口原因不能启动的解决方法

    在开启XAMPP的Apache时报出如下错误信息: 9:08:14 PM [Apache] Error: Apache shutdown unexpectedly.9:08:14 PM [Apache ...

  8. C# 加载图片image --(C#)Image.FromFile 方法会锁住文件的原因及可能的解决方法

    Image.FromFile 一旦使用后,对应的文件在一直调用其生成的Image对象被Disponse前都不会被解除锁定,这就造成了一个问题,就是在这个图形被解锁前无法对图像进行操作(比如删除,修改等 ...

  9. (C#)Image.FromFile 方法会锁住文件的原因及可能的解决方法

    Image.FromFile 一旦使用后,对应的文件在一直调用其生成的Image对象被Disponse前都不会被解除锁定,这就造成了一个问题,就是在这个图形被解锁前无法对图像进行操作(比如删除,修改等 ...

随机推荐

  1. JS中key-value存取

    获取Key 在代码中,遇到需要单独提取对象的key值时可使用 Object.keys(object) object是你需要操作的对象Object.keys()会返回一个存储对象中所有key值的数组获取 ...

  2. CentOS7创建启动脚本

    文件内容解释 [Unit]:服务的说明 Description:描述服务 After:描述服务类别 [Service]服务运行参数的设置 Type=forking是后台运行的形式 ExecStart为 ...

  3. nodejs接收post请求参数

    原文 https://blog.csdn.net/u013263917/article/details/78682270#1.2 nodejs接收post请求参数1.1-浏览器发送post请求参数的方 ...

  4. JOI2013-2019题解

    JOI2013-2019题解 Link

  5. Office 2016正式版/2019预览版 使用注意

    改写状态已经被隐藏 右击Word状态栏可以看到改写是否打开

  6. Linux下由于注释引发udf编译错误

    我们编写如下的UDF: 然后我们放到Linux下进行编译 Linux编译以后会报如下错误: 这是由于C语言的C90标准不支持行注释,而我们只需要将行注释修改为块注释 问题即可解决

  7. java web开发入门五(ssh整合)基于intellig idea

    SSH整合 1.引入jar包 Struts 核心jar Hibernate 核心jar Spring Core  核心功能 Web  对web模块支持 Aop   aop支持 Orm   对hiber ...

  8. OAuth2.0 自我领悟

    grant_type 授权模式 authorization_code 标准的Server授权模式,授权码模式 password 基于用户密码的授权模式,用户密码模式 client_credential ...

  9. Knative Serving 进阶: Knative Serving SDK 开发实践

    作者 | 阿里云智能事业群技术专家 牛秋霖(冬岛) 导读:通过前面的一系列文章你已经知道如何基于 kubectl 来操作 Knative 的各种资源.但是如果想要在项目中集成 Knative 仅仅使用 ...

  10. c# 自动给版本升级,遇9变0且前面一个版本加1

    /// <summary> /// 版本辅助类 /// 创建人: /// 创建时间:2019-11-18 13:53:55 /// </summary> public clas ...