“段”(Segment)是指二进制文件内的区域,所有某种特定类型信息被保存在这里。可以用size程序得到可执行文件中各个段的大小。
C程序布局中分为代码段、初始化数据段、非初始化数据段、栈段和堆段。
栈段空间的大小和操作系统有关。在Linux中,由系统命令ulimit指定,例如ulimit -a显示当前栈大小,而ulimit -s 32768将把栈大小指定为32MB。但在Windows中,栈大小是储存在可执行文件的。使用gcc可以这样制定可执行文件的栈大小:gcc -WI,--stack=16777216,这样栈大小就变为了16MB。
由栈溢出导致的段错误通常有以下原因:
- 递归调用层次太深:每次函数调用在内存栈中都需要分配空间,而每个进程的栈空间大小时有限的(VC6中栈内存默认大小为 1M)。当递归调用的层级太多时,就会超出栈的容量从而导致栈溢出。
- 局部变量占用空间太大,比如在栈大小为1M的空间中,如果定义局部变量int test[10000000]就会导致栈溢出。
解决方法:
方法一:用栈把递归转换成非递归
通常,一个函数在调用另一个函数之前,要作如下的事情:
a)将实参,返回地址等信息传递给被调用函数保存;
b)为被调用函数的局部变量分配存储区;
c)将控制转移到被调函数的入口.
从被调用函数返回调用函数之前,也要做三件事情:
a)保存被调函数的计算结果;
b)释放被调函数的数据区;
c)依照被调函数保存的返回地址将控制转移到调用函数.
所有的这些,不论是变量还是地址,本质上来说都是"数据",都是保存在系统所分配的栈中的.
那么自己就可以写一个栈来存储必要的数据,以减少系统负担。
方法二:使用全局数据段内存或者堆内存
可以直接把局部数组定义改成指针,然后动态申请内存;也可以把局部变量变成全局变量,一个偷懒的办法是直接在定义前边加个static,直接变成静态变量(实
方法三:增大堆栈大小值
参考:
http://blog.sina.com.cn/s/blog_606f9bd70100e51g.html
http://hi.baidu.com/sunboy_2050/item/45a62af463bfdc25753c4ccf