内存访问地址段错误

段错误 :

       1.段错误定义:

      段错误是指访问的内存超出了系统给这个程序所设定的内存空间,例如访问了不存在的内存地址、访问了系统保护的内存地址、访问了只读的内存地址等等情况。 

      2. 段错误产生的原因 :

       2.1 访问不存在的内存地址
       

#include<stdio.h> 
#include<stdlib.h> 
void main() 
{ 
int *ptr = NULL; 
*ptr = 0; 
} 
    2.2 访问系统保护的内存地址
    
#include<stdio.h> 
#include<stdlib.h> 
void main() 
{ 
int *ptr = (int *)0; 
*ptr = 100; 
} 
  2.3 访问只读的内存地址 
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
void main() 

char *ptr = "test"; 
strcpy(ptr, "TEST"); 
}
2.4 栈溢出
#include<stdio.h> 
#include<stdlib.h> 
void main() 
{ 
main(); 
} 



3. 段错误信息的获取 
程序发生段错误时,提示信息很少,下面有几种查看段错误的发生信息的途径。 

3.1 dmesg 
dmesg可以在应用程序crash掉时,显示内核中保存的相关信息。如下所示,通过dmesg命令可以查看发生段错误的程序名称、引起段错误发生的内存地址、指令指针地址、堆栈指针地址、错误代码、错误原因等。以程序2.3为例:


panfeng@ubuntu:~/segfault$ dmesg 
[ 2329.479037] segfault3[2700]: segfault at 80484e0 ip 00d2906a sp bfbbec3c error 7 in libc-2.10.1.so[cb4000+13e000] 
3.2 -g

4. 段错误的调试方法 
4.1 使用printf输出信息 
这个是看似最简单但往往很多情况下十分有效的调试方式,也许可以说是程序员用的最多的调试方式。简单来说,就是在程序的重要代码附近加上像printf这类输出信息,这样可以跟踪并打印出段错误在代码中可能出现的位置。 

为了方便使用这种方法,可以使用条件编译指令#ifdef DEBUG和#endif把printf函数包起来。这样在程序编译时,如果加上-DDEBUG参数就能查看调试信息;否则不加该参数就不会显示调试信息。

4.2 使用gcc和gdb 
4.2.1 调试步骤 
1、为了能够使用gdb调试程序,在编译阶段加上-g参数,以程序2.3为例:

panfeng@ubuntu:~/segfault$ gcc -g -o segfault3 segfault3.c

panfeng@ubuntu:~/segfault$ gdb ./segfault3 
GNU gdb (GDB) 7.0-ubuntu 
Copyright (C) 2009 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. Type "show copying" 
and "show warranty" for details. 
This GDB was configured as "i486-linux-gnu". 
For bug reporting instructions, please see: 
<http://www.gnu.org/software/gdb/bugs/>... 
Reading symbols from /home/panfeng/segfault/segfault3...done. 
(gdb)


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值