段错误与栈溢出

来源:互联网 发布:怎么屏蔽网络基站定位 编辑:程序博客网 时间:2024/05/14 11:41

“段”(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

原创粉丝点击