(编辑中)
一、理论:
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
//main.cpp
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b; 栈
char s[] = “abc”; 栈
char *p2; 栈
char *p3 = “”; \0在常量区,p3在栈上。
static int c =0; 全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得来得10和20字节的区域就在堆区。
strcpy(p1, “”); \0放在常量区,编译器可能会将它与p3所指向的””优化成一个地方。
}
http://www.cppblog.com/oosky/archive/2006/01/21/2958.html
二、溢出情况:
1、软件原因:
第二种解决办法是比较可行的,具体实现由很多种方法可以直接把数组定义改成指针,然后动态申请内存;也可以把局部变量变成全局变量,一个偷懒的办法是直接在定义前边加个static,呵呵,直接变成静态变量(实质就是全局变量)。即可以把上例中的函数这么写:
2、硬件(设置等)原因:
学习STM32F103 时遇到的堆栈溢出简单总结
关键词:STM32F 堆栈溢出 The stack pointer for stack ‘CSTACK’
前言:这两天在学习STM32F103的东西,LED也点亮了,在点LCD的时候遇到了问题,具体为在进入debug后,点击步进、步入、全速(step over、step into、step out、go)等按钮程序均跳到最后一行FFFFFFFF处(参见附图),无法调试。
在状态栏(log)给出提示为
但是把调试工具选为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=&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虚拟机的堆大小如何设置:命令行
java –Xms128m //JVM占用最小内存
–Xmx512m //JVM占用最大内存
–XX:PermSize=64m //最小堆大小
–XX:MaxPermSize=128m //最大堆大小
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/226480.html原文链接:https://javaforall.net

