段错误(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) 语句。这样,在下一次循环迭代时,程序就会对已经释放的指针进行解除引用操作,从而导致不可预料的结果。

相关文章推荐

linux C++ 莫名奇妙的段错误(segmentation fault),无法调用其它函数

进来在linux下开发C++项目,遇到了非常奇怪的bug。项目需要多线程实现,在写好代码后,每当运行到线程函数内部,当内部调用其它函数如printf、fopen等时就会提示段错误(segmentati...

用gdb检查段错误(segment fault)

原文地址::http://www.xxlinux.com/linux/article/development/soft/20070813/9274.html   简而言之,产生段错误就是访问了错误...

c/c++/qt中的段错误(segment fault)

关于内存的那些话就不说了,被一帮会装会转载的人说烂了 这里只说我在写程序时遇到段错误的原因,如何解决的 总之一句话,涉及到指针的,你不能在未定义,未初始化,未 “new” 之前使用,否则等待你的肯...

linnx内核出现段错误(segment fault)的调试方法

当你的程序在运行的过程中访问到空指针,那么linux系统就会出现非法访问内存错误,通常称为段错误(segmeng fault) 段错误分为用户态和内核态两种情况: 当用户态程序出现访问非法地址出现...

segment fault 段错误 (core dumped)的起因分析!

很久一致被这个问题,这里试着去理解理解,首先写一个程序:int main() {      int *p=(int *)malloc(0);      *p=10;      printf("...

使用gdb调试段错误(segment fault)

原文位置 http://www.unknownroad.com/rtfm/gdbtut/gdbsegfault.html     我们打算使用gdb去解决为什么下面的程序(文件为segfault...

嵌入式 使用gdb调试段错误(segment fault)

我们打算使用gdb去解决为什么下面的程序(文件为segfault.c)引起了段错误的问题。下面的这段程序是从用户那里读入一行文本字串然后显示在屏幕上。然而,如下当前的程序并不会如期执行... ...

第一时间捕获段错误(segment fault)的详细信息

不使用gdb也能捕获段错误的详细信息,事实上,使用gdb是一件很麻烦的事情!第一,gdb功能太过强大,诊断个段错误真是大材小用,如果不会用还要学...其次,很多系统并没有安装这个工具。因此最好的办法就...
  • dog250
  • dog250
  • 2011年08月20日 10:18
  • 7449

如果程序出现Segment fault错误,该如何排错?谈SIGBUS和SIGSEGV

2010年网易有道的一道考基础知识的面试题,如果程序出现Segment fault错误,该如何排错?那么,什么是Segment fault?这里笔者引用一篇文章,说的很清楚。 SIGBUS和...

linux之Segment Fault错误分析[1]

Linux环境下段错误的产生原因及调试方法小结 最近在Linux环境下做C语言项目,由于是在一个原有项目基础之上进行二次开发,而且项目工程庞大复杂,出现了不少问题,其中遇到最多、花费时间最长...
  • ee230
  • ee230
  • 2015年08月31日 11:30
  • 3328
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:段错误(Segment Fault!)莫名的问题 by fish
举报原因:
原因补充:

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