Chinaunix首页 | 论坛 | 博客
  • 博客访问: 376855
  • 博文数量: 44
  • 博客积分: 2060
  • 博客等级: 上尉
  • 技术积分: 528
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-17 20:50
文章分类
文章存档

2011年(1)

2010年(28)

2008年(15)

分类:

2010-03-08 13:55:38

2.指针越界和SIGSEGV
 

经常看到有帖子把两者混淆,而这两者的关系也确实微妙。在此,我们把指针运算(加减)引起的越界、野指针、空指针都归为指针越界。SIGSEGV在很多时候是由于指针越界引起的,但并不是所有的指针越界都会引发SIGSEGV。一个越界的指针,如果不解引用它,是不会引起SIGSEGV的。而即使解引用了一个越界的指针,也不一定会引起SIGSEGV。这听上去让人发疯,而实际情况确实如此。SIGSEGV涉及到操作系统、C库、编译器、链接器各方面的内容,我们以一些具体的例子来说明。

 

2.1错误的访问类型引起的SIGSEGV
 

  1 #include

  2 #include

  3    

  4 int main() {

  5     char* s = "hello world";

  6

  7     s[1] = 'H';

8 }

 

这是最常见的一个例子。想当年俺对C语言懵懂的时候,也在校内的BBS上发帖问过,当时还以为这是指针和数组的区别。此例中,”hello world”作为一个常量字符串,在编译后会被放在.rodata节(GCC),最后链接生成目标程序时.rodata节会被合并到text segment与代码段放在一起,故其所处内存区域是只读的。这就是错误的访问类型引起的SIGSEGV

其在图2中的顺序为:

1 -à 3 -à 4 -à 6 -à 8 -à 11 -à10

 

2.2访问了不属于进程地址空间的内存
 

  1 #include

  2 #include

  3    

  4 int main() {

  5     int* p = (int*)0xC0000fff;

  6

  7     *p = 10;

  8 }

在这个例子中,我们访问了一个属于内核的地址(IA3232bit)。当然,很少会有人这样写程序,但你的程序可能在不经意的情况下做出这样的行为(这个不经意的行为在后面讨论)。此例在图2的流程:

1 -à 2 -à 11 -à 10

 

2.3访问了不存在的内存
 

最常见的情况不外乎解引用空指针了,如:

  1 #include

  2 #include

  3    

  4 int main () {

  5     int *a = NULL;

  6

  7     *a = 1;

  8 }

 在实际情况中,此例中的空指针可能指向用户态地址空间,但其所指向的页面实际不存在。其产生SIGSEGV在图2中的流程为:

1 à 3 -à 4 -à 5 -à 11 -à10

阅读(4929) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~