free野指针会出现segment error!

野指针解释:(来自百度百科)

野指针的成因主要有三种:   

  一、指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。   

  二、指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针。 别看free和delete的名字(尤其是delete),它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉。通常会用语句if (p != NULL)进行防错处理。很遗憾,此时if语句起不到防错作用,因为即便p不是NULL指针,它也不指向合法的内存块。例:

#include <stdio.h>
#include <string.h>
#include <malloc.h>  

int main(void)
{
  char *p = (char *) malloc(100);
  strcpy(p, "hello"); 
  free(p);      // p 所指的内存被释放,但是p所指的地址仍然不变,原来的内存变为“垃圾”内存(不可用内存 
  if(p != NULL) // 没有起到防错作用     
  strcpy(p, "world");   
   for(i=0;i<5;i++){
     printf("%c",*(p++));//i=5后为乱码
     printf("\n");
}      
}  

   另外一个要注意的问题:不要返回指向栈内存的指针或引用,因为栈内存在函数结束时会被释放。  

  三、指针操作超越了变量的作用范围。这种情况让人防不胜防,示例程序如下:  

class A
  {
  public:
  void Func(void){ cout << “Func of class A” << endl; }
  };
  class B
  {
  public:
  A *p;
  void Test(void)
  {
  A a;
  p = &a; // 注意 a 的生命期 ,只在这个函数Test中,而不是整个class B
  }
  void Test1()
  {
  p->Func(); // p 是“野指针”
  }
  } 

函数 Test1 在执行语句 p->Func()时,对象 a 已经消失,而 p 是指向 a 的,所以 p 就成了“野指针” 。

  而segment error 就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gdtr来保存的,他是一个48位的寄存器,其中的32位是保存由它指向的gdt表,后13位保存相 应于gdt的下标,最后3位包括了程序是否在内存中以及程序的在cpu中的运行级别,指向的gdt是由以64位为一个单位的表。

  在这张表中就保存着程序运行的代码段以及数据段的起始地址以及与此相应的段限和页面交换还有程序运行级别还有内存粒度等等的信息。一旦一个程序发生了越界访问,cpu就会产生相应的异常保护,于是segmentation fault就出现了.

  所以当free 野指针时,说明访问了内存越界。。。。

  

posted on 2012-08-10 21:11  思维之墙  阅读(515)  评论(0编辑  收藏  举报

导航