(编辑中)

一、理论:

1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。

//main.cpp 
int a = 0; 全局初始化区 
char *p1; 全局未初始化区 
main() 

int b; 栈 
char s[] = "abc"; 栈 
char *p2; 栈 
char *p3 = "123456"; 123456\0在常量区,p3在栈上。 
static int c =0; 全局(静态)初始化区 
p1 = (char *)malloc(10); 
p2 = (char *)malloc(20); 
分配得来得10和20字节的区域就在堆区。 
strcpy(p1, "123456"); 123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。 
}

二、堆和栈的理论知识 
2.1申请方式 
stack: 
由系统自动分配。 例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间 
heap: 
需要程序员自己申请,并指明大小,在c中malloc函数 
如p1 = (char *)malloc(10); 
在C++中用new运算符 
如p2 = (char *)malloc(10); 但是注意p1、p2本身是在栈中的。

http://www.cppblog.com/oosky/archive/2006/01/21/2958.html

二、溢出情况:

1、软件原因:

最近在做一个程序(VC6.0),功能大概有网络通信、数据库、绘图等。测试的时候程序一运行到某个函数就出现此错误,查了很多地方,试了很多解决办法,终于把问题解决了,写个日志提醒一下自己,也希望作为一个普遍解决办法让大家少费工夫(其他编译器也会出现同样的问题)。
    大家都知道,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数据库),把栈内存还原,问题立刻消失。不知道究竟是什么原因,有知道的可以告诉我。
     email: la_ariza@sina.com

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

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

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

1、确设置堆栈,有利于掌握自己代码总共消耗了多少RAM资源
譬如实际消耗的堆栈可能需要100个,其他变量可能需要160个,按默认设置80个byte堆栈,或者你手动设为0,假设你芯片的RAM资源只有256,程序编译时不会给你报警,因为按你的设置,总共消耗80+160<256,但你实际跑起来,当最大堆栈用到100的时候,就肯定会跟一些变量重叠,引起跑飞
如果你知道自己消耗了堆栈100,手动把堆栈设为了100,那么编译器编译时就会提示你现在资源不够,防止你出错
程序堆栈的消耗,可以通过设置list文件包括内容来查看

2、硬件(设置等)原因:

学习STM32F103 时遇到的堆栈溢出简单总结

关键词:STM32F 堆栈溢出 The stack pointer for stack 'CSTACK'

前言:这两天在学习STM32F103的东西,LED也点亮了,在点LCD的时候遇到了问题,具体为在进入debug后,点击步进、步入、全速(step over、step into、step out、go)等按钮程序均跳到最后一行FFFFFFFF处(参见附图),无法调试。

在状态栏(log)给出提示为

Tue Oct 07 14:26:35 2008: Target reset
Tue Oct 07 14:26:38 2008: The stack 'CSTACK' is filled to 100% (1024 bytes used out of 1024). The warning threshold is set to 90.%
Tue Oct 07 14:26:38 2008: The stack pointer for stack 'CSTACK' (currently 0xFFFFFFFF) is outside the stack range (0x2000000C to 0x2000040C)
Tue Oct 07 14:26:39 2008: The stack 'CSTACK' is filled to 100% (1024 bytes used out of 1024). The warning threshold is set to 90.%
Tue Oct 07 14:26:39 2008: The stack pointer for stack 'CSTACK' (currently 0xFFFFFFFF) is outside the stack range (0x2000000C to 0x2000040C)

但是把调试工具选为simulator,即纯软件模式下无此问题。补充一下,编译工具为IAR 4.42 +jlink v6 选用swd模式

上网求助,先看看什么是堆栈?详情请参考百度百科http://baike.baidu.com/view/93201.htm

下面的解释是我抄来的 堆栈是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。要点:  堆:顺序随意 栈:后进先出(Last-In/First-Out) 一个由c/C++编译的程序占用的内存分为以下几个部分

  A、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

B、堆区(heap) — 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。

解决问题:以关键字“The stack pointer for stack 'CSTACK'”百度之,结果共三页,细细读之,参考发帖求助结果发现此类问题大概可以分为两种:

一:堆栈确实太小了,(大部分为此类问题,可惜我的问题不在此列)在*.xcl文件中调整,一般可以解决问题。下面列2个有代表性的帖子

http://www.ic37.com/htm_bbs_dic/2007-12/100131_480800.htm

http://group.ednchina.com/619/10215.aspx?page=1

二:程序中未对中断做初始化,程序跑飞了,也会出现这样的问题,参考sunke9这个帖子“报告icdev 我仿真的时候又被卡住了”   http://www.icdev.com.cn/bbs/viewthread.php?tid=8911

上面说过,搜索结果的3页的每个结果我都看了,花了半天的时间,不停的修改堆栈参数,检查中断初始化,但是都不能解决问题。最后又百度了一遍还是3页的结果,仔细看了下这个帖子“这样的警告怎么处理”

http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=779668&bbs_id=9999

里面网友tsb0574 阿波给出了解释 “出现这个问题一般有两种情况!!
1、确实是你的堆栈溢出了,在project->option->c/c++ Complier->system里面改大!!
2、为假相,是你的仿真器或者目标板出问题。仿真器在读取寄存器的值的时候出现问题。读过来的数据错误!!一般来说是第2种情况,第一种情况的话很少出现,除非传递结构体之类的大参数。”

回头仔细再看我的状态栏提示:

“Tue Oct 07 14:26:39 2008: The stack 'CSTACK' is filled to 100% (1024 bytes used out of 1024). The warning threshold is set to 90.% ”

想想我的程序很小就那么几行,1024 byte怎么会不够用呢,况且我改成了2048byte仍然提示不够用!难道是真的如阿波所言这是一个假象?目标板有问题?不太可能吧?仿真器问题?我的仿真器可是最新d版 v6 jlink啊,不管怎么样试试看吧,首先怀疑st的芯片swd模式有问题和jlink有冲突,于是改为jtag模式…嗯,很好,问题消失了。换用st linkII,依然没有问题,不过,st的芯片不至于这么烂吧?难道是jlink的swd模式有问题?更新jlink驱动为3.92a,再试,果然…嗯,只能说问题消失。似乎可以下结论了:jlink之前的驱动3.90d在swd模式下确实存在bug…

By the way ,开始点LED的时候没有出现问题,当我开始做IO映射,以便把STM32F103 的PB3,PB4用作GPIO时候发现这个问题,所以还以为我的io映射程序有问题,所以花了不少时间确认IO映射部分的程序,走了不少弯路。这里想再次问下该芯片的设计者,为啥不把JTAG口都放在PA或者PB上呢?

再顺便感谢一下ednchina 的 小可歌 和 ouravr 的tsb0574 阿波网友!

为了您的安全,请只打开来源可靠的网址

打开网站    取消

来自: http://hi.baidu.com/fpga_cpld/blog/item/17519c317a32e5ae5edf0ea9.html

三、解决方法:

1,什么是栈溢出?

因为栈一般默认为1-2m,一旦出现死循环或者是大量的递归调用,在不断的压栈过程中,造成栈容量超过1m而导致溢出。

2,解决方案:

方法一:用栈把递归转换成非递归

通常,一个函数在调用另一个函数之前,要作如下的事情:a)将实在参数,返回地址等信息传递给被调用函数保存; b)为被调用函数的局部变量分配存储区;c)将控制转移到被调函数的入口. 从被调用函数返回调用函数之前,也要做三件事情:a)保存被调函数的计算结果;b)释放被调函数的数据区;c)依照被调函数保存的返回地址将控制转移到调用函数.所有的这些,不论是变量还是地址,本质上来说都是"数据",都是保存在系统所分配的栈中的. 那么自己就可以写一个栈来存储必要的数据,以减少系统负担。

方法二:使用static对象替代nonstatic局部对象

在递归函数设计中,可以使用static对象替代nonstatic局部对象(即栈对象),这不仅可以减少每次递归调用和返回时产生和释放nonstatic对象的开销,而且static对象还可以保存递归调用的中间状态,并且可为各个调用层所访问。

方法三:增大堆栈大小值

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

Java在创建线程时设置栈大小:thread(threadgroup group, runnable target, string name, long stacksize)
         分配新的 thread 对象,以便将 target 作为其运行对象,将指定的 name 作为其名称,作为 group 所引用的线程组的一员,并具有指定的堆栈大小。

Java虚拟机的堆大小如何设置:命令行

 java –Xms128m   //JVM占用最小内存

–Xmx512m   //JVM占用最大内存

–XX:PermSize=64m   //最小堆大小

–XX:MaxPermSize=128m //最大堆大小

本文来自http://blog.csdn.net/luqiang454171826 ,引用必须注明出处!

【堆栈溢出】堆栈溢出相关推荐

  1. 堆栈 cookie 检测代码检测到基于堆栈的缓冲区溢出_WhatsApp缓冲区漏洞曝光 攻击者可通过MP4文件执行远程代码...

    Facebook 刚刚披露了 WhatsApp 缓冲区漏洞的部分细节.在上周的一份安全公告中,其表示 CVE-2019-11931 是由基于堆栈的缓冲区溢出 bug 引发,导致攻击者可向受害者发送精心 ...

  2. 检测到基于堆栈的缓冲区溢出_检测到堆栈粉碎

    检测到基于堆栈的缓冲区溢出 我敢打赌,每个Java开发人员在他们的职业生涯开始时第一次遇到Java代码的本机方法时都会感到惊讶. 我还可以肯定,多年来随着了解JVM如何通过JNI处理对本机实现的调用而 ...

  3. 堆栈的缓冲区溢出进不了系统_一文理解缓冲区溢出

    1 引言 "缓冲区溢出"对现代操作系统与编译器来讲已经不是什么大问题,但是作为一个合格的 C/C++ 程序员,还是完全有必要了解它的整个细节. 计算机程序一般都会使用到一些内存,这 ...

  4. 有未经处理的异常(在 xx.exe 中): 堆栈 Cookie 检测代码检测到基于堆栈的缓冲区溢出。

    有未经处理的异常(在 xx.exe 中): 堆栈 Cookie 检测代码检测到基于堆栈的缓冲区溢出. 参考文章: (1)有未经处理的异常(在 xx.exe 中): 堆栈 Cookie 检测代码检测到基 ...

  5. 堆栈 Cookie 检测代码检测到基于堆栈的缓冲区溢出

     报错:0x000CC3C9 处有未经处理的异常(在 image_opencv2.exe 中):  堆栈 Cookie 检测代码检测到基于堆栈的缓冲区溢出. 主要检查代码中有没有对数组的越界操作, ...

  6. 数据结构堆栈 内存堆栈_了解堆栈数据结构

    数据结构堆栈 内存堆栈 In this article, we'll be understanding the working and the need for the Stack Data Stru ...

  7. 内核堆栈 用户堆栈_弹性堆栈介绍

    内核堆栈 用户堆栈 当您运行对公司至关重要的软件时,您将无法拥有仅用于分析一段时间前发生的事情的日志,让客户端告诉您您的应用程序已损坏,而您甚至不知道发生了什么是真实的问题. 解决该问题的方法之一是使 ...

  8. 堆栈跟踪 堆栈跟踪_寻找缺少的堆栈跟踪

    堆栈跟踪 堆栈跟踪 我们最近在博客中发表的一篇评论带回了有关特定体验的一些回忆. 我希望我没有经历过的那种经历. 在创建Plumbr之前很长一段时间,我正在调试一个应用程序,该应用程序每次在蓝月亮时都 ...

  9. 内核堆栈 用户堆栈_堆栈痕迹从何而来?

    内核堆栈 用户堆栈 我相信,阅读和理解堆栈跟踪是每个程序员都必须具备的一项基本技能,以便有效地解决每种JVM语言的问题(另请参阅: 过滤日志中无关的堆栈跟踪行和首先记录引起根的异常 ). 那么我们可以 ...

  10. 堆栈 cookie 检测代码检测到基于堆栈的缓冲区溢出_漏洞公告 | 华硕(ASUS)家庭无线路由器远程代码执行0day...

     漏洞公告:  华硕(ASUS) RT系列是由华硕(ASUS)发布的针对家庭用户的中高端无线路由器,市场占用率比较高. 华硕路由器(ASUS)提供Web服务的组件存在一个设计缺陷:存在缓冲区溢出问题, ...

最新文章

  1. python中mod运算符_Python中的数学运算操作符使用进阶
  2. jquery - 动态绑定事件
  3. 原生JS实现苹果菜单
  4. mysql cmake错误_MySQL5.5安装出现CMake错误找不到CMakelists.txt原因-阿里云开发者社区...
  5. 使用Spring AOP和Guava速率限制器的节气门方法
  6. 嵌入式系统Linux内核开发工程师必须掌握的三十道题
  7. CentOS 7部署nfsen监控netflow
  8. 精华阅读第7期|程序员职业人生规划的三点建议
  9. 正态分布的前世今生:误差分布曲线的确立
  10. jQuery中文文档
  11. Python并发编程之多进程(实战)
  12. ssh-copy-id非22端口的使用方法
  13. Hexo框架下用NexT(v7.0+)主题美化博客
  14. IIS 6 元数据库与IIS 6 配置的兼容性 解决方案
  15. 文件一键上传、汉字转拼音、excel文件上传下载功能模块的实现
  16. pandas操作excel 笔记
  17. Java实现 LeetCode 513 找树左下角的值
  18. Essential singularity
  19. Python有证书吗?python证书是什么级别的呢?怎么才能达到python证书的考试条件呢?
  20. appinventor mysql_利用AppInventor实现登录功能(完整版).docx

热门文章

  1. 2018年深圳杯论文_2018.5.21/建模日记/深圳杯
  2. 计算机cad知识,计算机与Cad制图知识点.doc
  3. mac book usb 故障修复
  4. 主板usb接口全部失灵_usb接口没反应,主板usb接口全部失灵
  5. python判断成语是abac型_abac型词语成语大全
  6. Pygame教程系列三:绘制文本篇
  7. [渝粤教育] 南京邮电大学 Python语言程序设计基础 参考 资料
  8. 使用神经网络实现对天气的预测
  9. VOC2007.annotation文件解读
  10. 苹果手机来电归属地_如何批量计算手机号码的归属地?