内存篇之野指针

    前面两文中内存错误释放以及错误访问指向栈的指针,从另外角度,其中一部分错误还可以归结为访问了野指针。野指针又称悬挂指针,代表那些指向不可用内存区域的指针。操作野指针,程序会发生难以预料的错误。形成野指针主要有以下原因:

1)指针没有初始化。指针变量创建时不会自动指向null,其缺省值是随机的,比如:

    int *p;

    *p = 0;

    这种代码可能导致死机或者非法操作,所以使用指针前一定要初始化,使它指向分配好的可用空间,否则就成了野指针。

2)内存free后,指向内存的指针被误当作合法指针而继续使用。例如下例:

    char *p = (char *) malloc(100);

    strcpy(p, “hello”);

    free(p);          // p 所指的内存被释放,但是p所指的地址仍然不变

    ……

    if(p != NULL)    // 没有起到预防作用,因为p值未变

    strcpy(p, “world”); // 出错,访问野指针

    初学者在释放链表时也很容易犯类似错误:

    while (p)

    {

      free(p);

      q = p->next;    //p已释放,p->next是访问野指针

      p = q;

    }

    这里代码顺序很敏感,上面的顺序会导致野指针访问,正确方法是:

    while (p)

    {

      q= p->next;

      delete p;

      p= q;

    }

    如果多个指针指向同一内存,这一问题也经常发生。free某个指针释放了内存,其他指针即刻被悬挂成为野指针,如果不注意而继续访问就会出错。

3)指针指向失效的栈内存,比如:某子函数返回一指针,此指针指向子函数内部某局部变量,子函数退出后,该局部变量所在的栈内存就因自动出栈而释放,而这个返回的指针也就成了野指针,不能再使用了。具体见下节例子。

    总之,野指针和正常指针都指向某块内存,只是野指针所指的内存已不可用。就象一张失效的藏宝图,宝藏如果不在,藏宝图自然就成了废纸一张。所谓的悬挂也是表达类似含义。另外要注意区分野指针和空指针概念:野指针不特指空指针,而是指向垃圾(不可用)内存的指针。可以用if(ptr==null)预防空指针,但对野指针不起作用。所以野指针比空指针更隐蔽,危害更大。

    思考下,内存重复free的错误是不是第二次free访问了野指针?大家可以发表意见。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章