linux c 段错误

1.什么是段错误

  就是内存泄漏,访问了非法内存。要么指针为空,越界了,或者是本身地址非法,如0X00非法。

“所谓的段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gd
tr来保存的,他是一个48位的寄存器,其中的32位是保存由它指向的 gdt表,后13位保存
相应于gdt的下标,最后3位包括了程序是否在内存中以及程序的在cpu中的运行级别,指向
的gdt是由以64位为一个单位的表,在这张表中就保存着程序运行的代码段以及数据段的起
始地址以及与此相应的段限和页面交换还有程序运行级别还有内存粒度等等的信息。一旦
一个程序发生了越界访问,cpu就会产生相应的异常保护,于是segmentation fault就出现
了”http://blog.csdn.net/jeanblog/article/details/7005040

 

2.段错误的例子

  1.向地址0 NULL写东西,如 int i = 0;  scanf ("%d", i);;又如char *p; p = NULL;*p = 'x';

  2.地址越界:变量类型不一致等等:

          int b = 10;        printf("%s\n", b);   

        符串输出memset(buf, 0, 100);sprintf(buf, "%s", c);    //试图把char型按照字符串
        格式转换memset(buf, 0, 100);sprintf(buf, "%s", i);   //试图把int型按照字符串转  

     3.小结。

<1>定义了指针后记得初始化,在使用的时候记得判断是否为NULL
<2>在使用数组的时候是否被初始化,数组下标是否越界,数组元素是否存在等
<3>在变量处理的时候变量的格式控制是否合理等

3.如何发现段错误

http://blog.chinaunix.net/space.php?uid=317451&do=blog&id=92412。很强大啊。学习,膜拜。

4.补充,如何发现段错误

而我常用的调试方法有:

1)在程序内部的关键部位输出(printf)信息,那样可以跟踪 段错误 在代码中可能的位置
  为了方便使用这种调试方法,可以用条件编译指令#ifdef DEBUG和#endif把printf函数给包含起来,编译的时候加上

-DDEBUG参数就可以查看调试信息。反之,不加上该参数进行调试就可以。

2)用gdb来调试,在运行到段错误的地方,会自动停下来并显示出错的行和行号

  编译的时候加上-g参数,用来显示调试信息,

  通过扑获SIGSEGV信号来触发调用gdb来输出调试信息。可以通过man 7 signal查看SIGSEGV的信息。
Quote:

      falcon@falcon:~/temp$ man 7 signal | grep SEGV
              Reformatting signal(7), please wait...
               SIGSEGV      11       Core    Invalid memory reference
3)还有一个catchsegv命令
通过查看帮助信息,可以看到
Quote:

Catch segmentation faults in programs

这个东西就是用来扑获段错误的,不过打印出来的是一些register里头的东西,“看不太
懂”。

3.总结,

  指针必须要判断是否为空。返回的指针值判断是否为我们想要的值。

posted @ 2012-08-30 20:03  dreamboke  阅读(464)  评论(0编辑  收藏  举报