段错误(Segment Fault!)莫名的问题 by fish

原创 2007年09月30日 14:17:00
 

段错误或段违规(segmentation violation)应该已经很清楚,之前有过一篇文章介绍过“段模型”。

在一般硬件中,段错误是由于“内存管理单元”(负责支持虚拟内存的硬件)的异常所致,而该异常则通常是由于解除引用一个未初始化或非法值的指针引起的。如果指针引用一个并不位于你的地址空间中的地址,操作系统便会对此进行干涉。一个小型的会引起段错误的程序如下:

int *p = 0;
*p = 17;     //引起一个段错误

一个微妙之处是,导致指针具有非法的值通常是由于不同的编程错误所引起的。和总线错误不同,段错误更像是一个间接的症状而不是引起错误的原因。

一个更糟糕的微妙之处是,如果未初始化的指针恰好具有未对齐的值(对于指针所要访问的数据而言),它将会产生总线错误,而不是段错误。对于绝大多数架构的计算机而言确实如此,因为CPU先看到地址,然后再把它发送给MMU(内存管理单元)。 


 

通常导致段错误的几个直接原因:

(1)解除引用一个包含非法值的指针;

(2)解除引用一个空指针(常常由于从系统程序中返回空指针,并未经检查就使用)。

(3)在未得到正确的权限时进行访问。例如,试图往一个只写的文本段存储值就会引起段错误。

(4)用完了堆栈或堆空间(虚拟内存虽然巨大但绝非无限)。

下面这个说法可能过于简单,但在绝大多数架构的绝大多数情况下,总线错误意味着CPU对进程引用内存的一些做法不满,而段错误则是MMU对进程引用内存的一些情况发生抱怨。

以发生频率为序,最终可能导致段错误的常见编程错误是:

1。坏指针值错误:在指针赋值之前就用它来引用内存,或者向库函数传送一个坏指针(不要上当!如果编译器显示系统程序中出现了段错误,并不是因为系统程序引起了段错误,问题很可能还在存在于自己的代码中)。第三种可能导致坏指针的原因是对指针进行释放之后再访问它的内容。可以修改free语句,在指针释放之后再将它置为空值。

free(p);  p = NULL;

这样,如果在指针释放之后继续使用该指针,至少程序能在终止之前进行信息转储。

2。改写(overwrite)错误:越过数组边界写入数据,在动态分配的内存两端之外写入数据,或改写一些堆管理数据结构(在动态分配的内存之前的区域写入数据就很容易发生这种情况)。

p = malloc(256);  p[-1] = 0;  p[256] = 0;

3。指针释放引起的错误:释放同一个内存块两次,或释放一块未曾使用malloc分配的内存,或释放仍在使用中的内存,或释放一个无效的指针。一个极为常见的与释放内存有关的错误就是在 for(p=start; p; p=p->next)这样的循环中迭代一个链表,并在循环体内使用 free(p) 语句。这样,在下一次循环迭代时,程序就会对已经释放的指针进行解除引用操作,从而导致不可预料的结果。

总线错误和段错误问题的定位

对现在的很多初级的程序原来说如果遇到总线错误(bus error)或者段错误(segementation fault/ core dump)是一件非常折磨人的事,让人一时间找不到什么好的方法也不知从何...
  • xipiaoyouzi
  • xipiaoyouzi
  • 2013年06月29日 16:20
  • 3661

【记录】memcpy后报错:segmentation fault

问题:使用v4l2框架进行图像数据采集,遇到在执行memcpy()函数时报错segmentation fault 开发环境:ubuntu和ARM开发板(Linux+Qt系统) 实验做的代码如下(只...
  • u011831771
  • u011831771
  • 2017年12月14日 15:55
  • 50

总线错误和段错误问题的定位

对现在的很多初级的程序原来说如果遇到总线错误(bus error)或者段错误(segementation fault/ core dump)是一件非常折磨人的事,让人一时间找不到什么好的方法也不知从何...
  • maochengtao
  • maochengtao
  • 2014年10月22日 11:10
  • 297

异常和段错误如何产生的

异常和段错误如何产生的 http://www.cnblogs.com/davy2013/archive/2013/07/02.html
  • zuihoudebingwen
  • zuihoudebingwen
  • 2013年08月25日 20:36
  • 942

linux吐核详解——详解coredump

谢谢大神,把吐核原因分析的很清楚,先转载部分,原文在这里 详解coredump 。 五,coredump产生的几种可能情况 造成程序coredump的原因有很多,这里总结一些比较常用的经验吧:  ...
  • yiranant
  • yiranant
  • 2015年06月10日 10:54
  • 4789

你的C/C++程序为什么无法运行?揭秘Segmentation fault (2)

什么让你对C/C++如此恐惧?本篇将继续上一篇来讨论段错误(Segmentation fault)。 上一篇: 你的C/C++程序为什么无法运行?揭秘Segmentation fault (cor...
  • gsky1986
  • gsky1986
  • 2015年04月29日 23:15
  • 8158

linux 下 C 编程 C版的try catch 捕捉段错误和异常处理

哇塞,C语言有try catch吗?当然没有。倒。。可能有人说了,那你野鬼说没有的东西做什么。      这里需要重申一下,所谓正向设计下问题检测的开发方法。正向设计时,在错误检测和问题修复的方...
  • Emilio563
  • Emilio563
  • 2016年02月18日 13:05
  • 2132

MMU

现代操作系统普遍采用虚拟内存管理( Virtual Memory Management) 机制,这需 要MMU( Memory Management Unit,内存管理单元) 的支持。有些嵌入式...
  • jinqg
  • jinqg
  • 2016年12月01日 15:27
  • 210

PAT乙级.1032. 挖掘机技术哪家强(20)

1032. 挖掘机技术哪家强(20) 题目: 为了用事实说明挖掘机技术到底哪家强,PAT组织了一场挖掘机技能大赛。现请你根据比赛结果统计出技术最强的那个学校。 输入格式 输入在第1行给出不超过...
  • R11happy
  • R11happy
  • 2016年08月11日 21:40
  • 833

浙大ZOJ 1009 Enigma问题解决及别人的解决方案

教训:在这题上浪费太多次机会了,因为以下几个原因: 1. 没考虑到m(m为轮子字母表的规模)为1的情况,从而导致出现“Floating Point Error”。通过将“if(i!=0&&i%(m-...
  • xiaogugood
  • xiaogugood
  • 2014年01月06日 17:16
  • 1654
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:段错误(Segment Fault!)莫名的问题 by fish
举报原因:
原因补充:

(最多只允许输入30个字)