以下内容为网络资源结合自身实践的总结,在此首先感谢提供资源的各位网友。

大家都知道,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。

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

如果是英文版: 
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 】

学过编译原理就知道,函数栈空间是用于存放局部变量、函数返回地址以及函数参数等数据的内存区域,其大小是有限的(VC6默认是1MB)。当局部变量占用空间太大,或者函数调用层次太深就会出现“Stack Overflow”的情况。最经常出现的错误有以下两种:

1.局部数组变量空间太大,如下:

intmain(int argc, char* argv[])

{

char stack_overflow[1024*1024*5];

stack_overflow[0] = 1;

return 0;

}

解决这类问题的办法有两个,一是增大栈空间(后文中有详细描述),二是改用动态分配,使用堆(heap)而不是栈(stack)。

2.函数出现无限递归调用,如下:

voidinfinite_loop()

{

infinite_loop();

}

intmain(int argc, char* argv[])

{

infinite_loop();

return 0;

}

解决方法便很多,如下:

1.增大栈空间

调出“Project/Settings/Link”选项卡,选择Output,其中的Stack allocations的reserve值便是栈空间所用大小(见下图),VC6中默认为1MB,根据实际情况将其加大然后重新编译即可,具体说明可参见MSDN中的/stack选项。这个方案对于一些问题来说简单可行,但不能满足我这里的需求。

这里再多提一点,增大栈空间还有一个更简单的方法,那就是使用VC附带的EDITBIN工具,它可以直接增大可执行程序的栈空间,而不用重新编译程序,其使用方法如下:

EDITBIN/STACK:reserve[,commit] [files]

2.限制队列长度

这个方法不能满足我的应用需求,因此不可行。

3.改用其它方式实现消息队列

即不使用boost::shared_ptr,改用原始指针或者std::list来构建消息队列。但我的程序的模型比前面给出的测试代码要复杂得多,牵扯到其它方面的因素,因此该方法也不太可行。

4.断开消息队列

这是我最后采用的方案,析构时的迭代之所以会发生,是源于boost::shared_ptr的引用计数原理,只要将消息链断开就不会有这样的问题。针对前面的测试例子,只要在return 0前面加上如下代码即可避免“Stack Overflow”:

pCur = pHead;

for(i=1; i// 依次断开消息链

{

pHead = pCur->m_pNext;

pCur->m_pNext.reset();

pCur = pHead;

}

同样在VS2008里,我也遇到了同样的问题,方法同上面的差不多!

方法:项目->属性->链接器->系统->堆栈保留大小(设置同VC++6.0的一样)

VS或VC编译正常,但运行时出现Stack overflow相关推荐

  1. Qt编译通过,运行时出现the process was ended forcefully问题的解决方案

    ** Qt编译通过,运行时出现the process was ended forcefully问题的解决方案 ** Debug和Release模式下编译均能通过,调用外部函数也不会提示错误,但是运行就 ...

  2. java多态编译,java多态 运行时多态和编译时多态

    java多态 运行时多态和编译时多态 我们知道java的多态是一个重要的特性,其中体现java的多态有两种形式.运行时的多态和编译时的多态. 编译时的多态会发生在方法重载的时候,方法的重载指方法名相同 ...

  3. 【QT】QT Creator编译通过,运行时程序异常结束:Crashed

    最近有个小项目需要用QT写,奈何没玩过QT,踩了不少坑,这里给大家写一下避避雷. 编译通过,运行异常时报错如下: 这个异常很诡异,什么提示都不给你,网上找了很久,被折磨了快两天了,这里提供给新人一个偷 ...

  4. 使用std::thread线程相关函数,-static静态编译的程序运行时的一些常见错误

    使用std::thread的应用程序,编译时如果是动态链接pthread线程库运行正常,-static静态链接时在某些平台下可能会遇到一些意外错误.如常见编译命令:g++ -std=C++11 tes ...

  5. QT编译的程序运行时缺少DLL如何处理

    编译完QT的程序后,如果在其他地方运行缺少DLL,可以这样做: 在安装有QT5的计算机上,进入QT5的命令行,进入EXE或DLL所在的目录 运行windeployqt filename(这个filen ...

  6. Qt编译通过,运行时出现the process was ended forcefully的crashed问题

    一般在编译QT的时候,如果出现程序异常结束,首先要先确保是不是引入的动态库有问题,找到debug目录,把所引入的动态库复制进行即可找到. 我的动态库没有问题,这是代码做了改变之后出现了这种问题,网上还 ...

  7. 编译时异常与运行时异常

    在实际开发中,经常会在程序编译时产生一些异常,必须要对这些异常进行处理,这种异常称为编译时异常,也称为checked异常.另外,还有一种异常是在程序运行时产生的,这种异常即使不编写异常处理代码,依然可 ...

  8. 趣谈iOS运行时的方法调用原理

    一个成熟的计算机语言必然有丰富的体系,复杂的容错机制,处理逻辑以及判断逻辑.但这些复杂的逻辑都是围绕一个主线丰富和展开的,所以在学习计算机语言的时候,先掌握核心,然后了解其原理,明白程序语言设计的实质 ...

  9. ORB-SLAM3运行时出现“段错误(核心已转储)”解决方案

    编译成功,运行时如下图 在ubuntu20上运行kitti双目数据集时: 解决方案 这是由于Settings.cc文件中有逻辑错误,在重载输出流运算符时,当相机类型为stereo,且为Rectifie ...

最新文章

  1. 你应该知道的 Nginx 配置清单
  2. Prometheus监控的最佳实践——关于监控的3项关键指标
  3. 最新架构amd服务器cpu,AMD Zen架构处理器全新性能配置介绍
  4. Using Preferences(Beginning Android)
  5. C++ 读取windows服务列表 与操作注册表
  6. 关于Axure RP
  7. 今日早上出来还是阴天
  8. 三菱fx3u中文手册_3个月高效掌握三菱PLC!四个阶段经验大总结~
  9. mysql 2049_mysql数据库备份与还原,解决40101和ERROR 2049错误
  10. VS2017离线下载 -- 如何让VS2017不占用C盘
  11. 第一波养老目标基金来袭及9个看点回顾
  12. 计算机桌面壁纸希望,电脑励志的图片桌面壁纸
  13. java基于springboot+vue的学生宿舍报修管理系统(源码+数据库+Lw文档)
  14. 修改登录密码html代码,html登录界面设置账号密码
  15. 考研数学 第7讲 零点问题和微分不定式
  16. 3D打印肝模型抢救生命
  17. Jmeter 录制手机脚本
  18. oracle配置文件
  19. 服务器虚拟化书籍,服务器虚拟化解决方案书模板-精选版.doc
  20. 苹果屏蔽更新描述文件_屏蔽描述文件失效!iOS13屏蔽系统更新方法推荐

热门文章

  1. python3爬取微博评论教程_用python 爬取微博评论,怎么打开微博评论下的查看更多|...
  2. 运营商再次大规模建设新5G网络,用户或被迫更换5G手机
  3. 【日常折腾】重新安装Windows7,做好ghost备份,迁移主目录,日常软件office,chrome,搜狗输入法,电脑管家,一键ghost进行备份。
  4. 每日优鲜完成新一轮4.5亿美元融资,自有品牌商品占比j将提升至50%
  5. Uboot代码结构详细分析
  6. 怎样来实现数据接口的加密?
  7. 第10次Scrum会议(10/22)【欢迎来怼】
  8. 指令流水线 —— 分类和多发技术
  9. 中国篆刻艺术孙溟㠭作品《无有中无尽藏》
  10. ArcGIS Online试用版注册 并发布要素服务