VC++中,在栈空间上申请存储的结构体或者类对象的数组空间时,如果数组长度过大,造成申请的栈空间超过或者逼近1MB时,程序可以编译通过,但是不能够执行起来。打到调试模式时会弹出如下图所示的栈空间越界错误对话框。

如下面的类定义:

  1. class Character
  2. {
  3. public:
  4. Character()
  5. {
  6. x0 = ;
  7. y0 = ;
  8. x1 = ;
  9. y1 = ;
  10. offsetX = ;
  11. offsetY = ;
  12. }
  13.  
  14. unsigned int x0:;
  15. unsigned int y0:;
  16. unsigned int x1:;
  17. unsigned int y1:;
  18. unsigned int offsetX:;
  19. unsigned int offsetY:;
  20. unsigned int texIndex:;
  21. };

  而FreeTypeFont类中申请了65536个Character类数组,如下代码:

  1. class FreeTypeFont
  2. {
  3. public:
  4. FT_Library _library;
  5. FT_Face _face;
  6. unsigned _sysFontTexture;
  7. Character _character[1<<16];
  8.    int _textureWidth;
  9. int _textureHeight;
  10. //! 临时变量,保存当前字体写到文理上的位置坐标
  11. int _yStart;
  12. int _xStart;
  13. //! 字体大小
  14. int _fontSize;
  15. //! 上述字体的大小并不是字体的像素大小,所以需要用一个变量来计算字体的像素大小
  16. int _fontPixelX;
  17. int _fontPixelY;
  18. bool _isSymbol;
  19. char _vertexBuffer[ * ];
  20. }

  产生stack overflow错误提示框:

  把project设置里的堆栈加大就可以了,默认是1M,你可以加大到10M试试. 
      project->setting->link:  
    在category里选择output,在stack的Reserve里输入0x10000000试试 。具体设置如图:

  

每当创建一个线程时,系统就会为线程的堆栈(每个线程有它自己的堆栈)保留一个堆栈空间区域,并将一些物理存储器提交给这个已保留的区域。按照默认设置, 系统保留1MB的地址空间并提交两个页面的内存。但是,这些默认值是可以修改的,方法是在你链接应用程序时设定Microsoft的链接程序的 /STACK选项:

      /STACK:reserve[,commit]  
    当创建一个线程的堆栈时,系统将会保留一个链接程序的/STACK开关指明的地址空间区域。但是,当调用CreateThread或 _beginthreadex函数时,可以重载原先提交的内存数量。这两个函数都有一个参数,可以用来重载原先提交给堆栈的地址空间的内存数量。如果设定 这个参数为0,那么系统将使用/STACK开关指明的已提交的堆栈大小值。后面将假定我们使用默认的堆栈大小值,即1MB的保留区域,每次提交一个页面的 内存。

  ===========================================================华丽的分割线===========================================================

在解释原因前我们先看一下一个由C/C++编译的程序占用的内存分为几个部分:

1、栈区(stack segment):由编译器自动分配释放,存放函数的参数的值,局部变量的值等。在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。

2、堆区(heap segment) : 一般由程序员分配释放,若程序员不释放,程序结束时可能由系统回收 。它与数据结构中的堆是两回事。堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

3、全局区(静态区)(data segment):全局变量和静态变量的存储区域是在一起的,程序结束后由系统释放。数据区的大小由系统限定,一般很大。

4、文字常量区:常量字符串就是放在这里的, 程序结束后由系统释放。

5、程序代码区:存放函数体的二进制代码。

综上所述,局部变量空间是很小的,我们开一个a[1000000]就会导致栈溢出;而全局变量空间在Win 32bit 下可以达到4GB,因此不会溢出。

VC6.0中修改堆栈大小的方法:

1). 选择 "Project->Setting".
 2). 选择 "Link".
 3. 选择 "Category"中的 "Output".
 4. 在 "Stack allocations"中的"Reserve:"中输栈的大小,例如: 32768

在VS2010中设置堆栈大小的方法为:

1). 选择 "项目->属性".
2). 选择 "链接器".
3. 选择 "系统".
4. 在 "堆栈保留大小"中输栈的大小,例如: 32768 。

VC++中出现stack overflow错误时修改VC++的默认堆栈大小的更多相关文章

  1. IE中出现 "Stack overflow at line" 错误的解决方法

    在做网站时遇到一个问题,网站用的以前的程序,在没有改过什么程序的情况下,页面总是提示Stack overflow at line 0的错误,而以前的网站都正常没有出现过这种情况,在网上找了一下解决办法 ...

  2. mysql登录1045错误时 修改登录密码

    1.进入 mysql 的 bin 目录下,打开 cmd ,关闭 mysql 数据库. 2.输入 mysqld --skip-grant-tables 回车. 保持窗口不要更改不要关闭 (--skip- ...

  3. VC调试篇:ASSERT(FALSE)时怎么办?查看调用堆栈

    问题简述 我们在调试程序时,经常会遇到程序中断的情况,就像下图这样. 我艹,这该怎么办,我们一下子就懵逼了.我们选择中断,常常会跳到一个莫名其妙的地方去. 正是这个断言 ASSERT(::IsWind ...

  4. Stack overflow 编译能通过,运行时出现Stack overflow

    Stack overflow 编译能通过,运行时出现Stack overflow 大家都知道,Windows程序的内存机制大概是这样的,全局变量(局部的静态变量本质也属于此范围)存储于堆内存,该段内存 ...

  5. stack overflow错误分析

    stack overflow(堆栈溢出)就是不顾堆栈中分配的局部数据块大小,向该数据块写入了过多的数据,导致数据越界,结果覆盖了老的堆栈数据. 或者解释为 在长字符串中嵌入一段代码,并将过程的返回地址 ...

  6. VC++学习之VC中常见问题

    VC++学习之VC中常见问题 (1)为什么某个类突然在工作区间里面突然看不见了? 只是类隐藏了,打开FILEVIEW,找到隐藏类的头文件,随便敲一下键盘的空格键,类就会在CLASSVIEW中显示了 ( ...

  7. VC中GetLastError()获取错误信息的使用,以及错误代码的含义

    转载:http://www.seacha.com/article.php/knowledge/windows/mfc/2011/0423/335.html VC中GetLastError()获取错误信 ...

  8. Stack的三种含义(数据超过栈的大小,就发生stack overflow)

    非常典型的基础知识,转自http://www.ruanyifeng.com/blog/2013/11/stack.html 学习编程的时候,经常会看到stack这个词,它的中文名字叫做"栈& ...

  9. VC中键盘键的对应关系

    转载:VC中如何响应键盘和鼠标事件 VC 中用 KeyPress 表示键盘响应的所有事件,包括 OnKeyDown 事件(键按下). OnKeyUp 事件(键按下后弹起)和 OnKeyPress 事件 ...

随机推荐

  1. c#如何禁用win7的任务管理器

    以前制作的桌面锁屏软件虽然也禁用过任务管理器,但是采取的是比较笨的方法,而且对操作系统还有一定的危害.因为任务管理也是一个窗体也就是说它中也是一个独立进程,所以只需要强制性关闭这个进程即可以关闭任务管 ...

  2. 怎么配置eclipse的联想功能

    第一步:打开Eclipse,windows下,打开“window”→“Preferences” :mac下,打开“偏好设置”. 第二步:选择“Java”,展开,“Editor”,选择“Content ...

  3. 网络 TCP三次握手及滑动窗口

    三次握手客户端向服务器发出触发请求syn=1:因为这时还没有得到服务器的回应,所以ack=0服务器接收到客户端的触发请求,回复ack=1,表示已经接收到客户端的请求:同时服务器也向客户端发出触发请求, ...

  4. gearman入门初步

    原文地址:http://blog.sina.com.cn/s/blog_5f54f0be0101btsi.html     PHP 没有提供直接的并发功能.要实现并发,必须: function asy ...

  5. webapp开发绝对定位引发的问题

    最近做了一个webapp 需求是要滑动页面翻页,我使用了大量绝对定位 当遇到输入框时,在部分手机上发现了问题.虚拟键盘收回时,整个body全部下移了,经过多次测试, 发现是fixed布局的音乐按钮造成 ...

  6. mocha、chai、sinon和istanbul实现100%单元测试覆盖率

    敏捷软件开发中,最重要实践的就是测试驱动开发,在单元测试层面,我们试着实现一个重要的指标就是测试覆盖率.测试覆盖率衡量我们的代码是否已经全部被测试到了. 但是指标本身不是目的,借助测试覆盖率检查,我们 ...

  7. 将 ExpressRoute 线路从经典部署模型转移到 Resource Manager 部署模型

    本文概述将 Azure ExpressRoute 线路从经典部署模型转移到 Azure Resource Manager 部署模型的效果. Azure 当前使用两种部署模型:Resource Mana ...

  8. Oracle EBS AR 删除应收发票

    DECLARE    -- Non-scalar parameters require additional processing     p_errors arp_trx_validate.mess ...

  9. Oracle ALL DBA表

    select * from all_tab_comments -- 查询所有用户的表,视图等 select * from user_tab_comments -- 查询本用户的表,视图等 select ...

  10. Sql Server中的谓词和运算符

    谓词和运算符配合使用是我们得到理想数据的最佳途径. 一.浅谈谓词 谓词的概念:一个运算结果为True.False或Unknown的逻辑表达式.它的运用范围有:where子句.Having子句.Chec ...