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 】
Stack overflow 编译能通过,运行时出现Stack overflow的更多相关文章
- Java源文件编译成功但是运行时加载不到文件
最近系统重装了一些,Java等环境变量都需要重新配置,配置好以后编写了一个Java源文件编译了一下,通过Javac编译源文件,编译成功,但是再通过Java运行时没找到报出找不到加载文件或者加载文件不存 ...
- gcc新版本号引起的编译错误(命令运行时的外部库输入位置)
昨天,遇到一个比較bug的错误,用gcc来编译几个简单的文件出错,编译环境为x86_64的Ubuntu12.04.gcc版本号号例如以下: gcc (Ubuntu/Linaro 4.6.3-1ubun ...
- android apk 防止反编译技术第二篇-运行时修改字节码
上一篇我们讲了apk防止反编译技术中的加壳技术,如果有不明白的可以查看我的上一篇博客http://my.oschina.net/u/2323218/blog/393372.接下来我们将介绍另一种防止a ...
- android apk 防止反编译技术第二篇-运行时修改Dalvik指令
上一篇我们讲了apk防止反编译技术中的加壳技术,如果有不明白的可以查看我的上一篇博客http://my.oschina.net/u/2323218/blog/393372.接下来我们将介绍另一种防止a ...
- Java内存区域(运行时数据区域)和内存模型(JMM)
Java 内存区域和内存模型是不一样的东西,内存区域是指 Jvm 运行时将数据分区域存储,强调对内存空间的划分. 而内存模型(Java Memory Model,简称 JMM )是定义了线程和主内存之 ...
- 趣谈iOS运行时的方法调用原理
一个成熟的计算机语言必然有丰富的体系,复杂的容错机制,处理逻辑以及判断逻辑.但这些复杂的逻辑都是围绕一个主线丰富和展开的,所以在学习计算机语言的时候,先掌握核心,然后了解其原理,明白程序语言设计的实质 ...
- gcc编译通过,运行却显示“段错误”的解决方法
第一次在Liunx上(liunx mint 17)使用gcc编译c文件,竟然提示“找不到stdio.h",经过google后发现执行 sudo apt-get install build- ...
- Vue2的独立构建与运行时构建的差别
其实这个问题在你使用vue-cli构建项目的时候是不会出现的,因为你在创建项目的构建过程中已经让你勾选了,然后会写入webpack.config.js中. 这就在这,会让你选择Vue的构建方式. 如果 ...
- Java检查异常、非检查异常、运行时异常、非运行时异常的区别
Java把所有的非正常情况分为两种:异常(Exception)和错误(Error),它们都继承Throwable父类. Java的异常(Exception和Error)分为检查异常和非检查的异常. 其 ...
随机推荐
- 如何利用Python词云和wordart可视化工具对朋友圈数据进行可视化展示
大前天我们通过Python网络爬虫对朋友圈的数据进行了抓取,感兴趣的朋友可以点击进行查看,如何利用Python网络爬虫抓取微信朋友圈的动态(上)和如何利用Python网络爬虫爬取微信朋友圈动态——附代 ...
- codeforces 140E.New Year Garland
传送门: 解题思路: 要求相邻两行小球颜色集合不同,并且限制行内小球相邻不同. 由此可得:每行小球排列都是独立与外界的, 所以答案应该是对于所有行的颜色集合分类,在将行内的答案乘到上面. 先考虑如何分 ...
- CodeForcesGym 100502D Dice Game
Dice Game Time Limit: 1000ms Memory Limit: 524288KB This problem will be judged on CodeForcesGym. Or ...
- DataGirdView 常用操作
1.将数据源的某列添加到已有DataGirdView的列 例如:将文件夹下所有文件名添加到DataGirdView 的文件名一列,图片如下: 首先在datagridview把文件名列的DATAPROP ...
- SQL 自增列清零方法
SQL Identity自增列清零方法1.使用DBCC控制台命令: dbcc checkident(表名,RESEED,0) 2.truncate table 也可将当前标识值清零 但当有外键等约束时 ...
- 11.2.0.1升级到11.2.0.4报错之中的一个:UtilSession failed: Patch 9413827
UtilSession failed: Patch 9413827 requires component(s) that are not installed in OracleHome. These ...
- Objective-C(十九、通知-消息发送模式之中的一个)——iOS开发基础
结合之前的学习笔记以及參考<Objective-C编程全解(第三版)>,对Objective-C知识点进行梳理总结. 知识点一直在变.仅仅是作为參考.以苹果官方文档为准~ 十九.通知-消息 ...
- 怎样更好的设计android图标,拉伸不变形等等系列长处,并且减小apk大小
android mvp框架:dileber(https://github.com/dileber/dileber.git) 继续为大家介绍android mvp开源框架 dileber 今天主要是字 ...
- iOS使用push隐藏子页面底部bottom TabBar
下面两种情况是我在开发过程中遇到的,一种是代码使用pushViewController,还有一种是storyboard直接使用push.之前也查阅了非常多关于隐藏底部tabbar的资料.可是要么使用起 ...
- sqlserver 小计合计总计
SELECT CASE WHEN GROUPING(F1) = 1 THEN '总计'WHEN GROUPING(F1) = 0 AND GROUPING(F2) = 1 THEN F1+'合计'W ...