野指针的四大问法

一、什么是野指针

  野指针是指向不可用内存区域的指针

二、如何产生野指针

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

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

举例:

char *p = (char *) malloc(100); 
strcpy(p, “hello”); 
free(p); // p 所指的内存被释放,但是p所指的地址仍然不变 
if(p != NULL) // 没有起到防错作用 
strcpy(p, “world”); // 出错 

三、野指针的危害

(1)使用野指针易应内存泄漏出现段错误

而造成内存泄漏的原因有两个

(1)访问了没有权限的内存(平时我们正确使用指针的时候,系统已经将相应的内存分配给用户,但是如果指向没有分配的内存,系统会判定我们没有权限)

(2)访问了已经释放了的内

 

四、腾讯面试题:

#include 'stdafx.h'  
#include <iostream> 
#include <string> 
using std::cout; 
using std::endl; 
class Test 
{ 
public: 
Test() 
{ 
    a = 9; 
    delete this; 
} 
~Test() 
{ 
    cout<<'destructor called!'<<endl; 
} 
    int a; 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    Test *mytest = new Test(); //mytest的值和this指针的值是一样一样的 
    cout<<mytest->a<<endl; 
    return 0; 
} 

1

请问运行结果如何?

常见的回答,程序会报错,通不过编译。或者说编译通过,运行时报错,因为居然Test类的构造函数删除了this指针,相当于调用了Test类的析构函数,对象不再存在,所以访问成员变量a的时候出错。

实际的结果是,程序可以通过编译,运行时不报错,只不过打印出a的值不是9,而是内存中一个随机垃圾值。

如果想让程序运行时出错,可以这样写main函数:

Test mytest;
cout<<mytest.a<<endl;
return 0;

这样mytest是局部对象,内存在栈上分配,delete this试图释放栈上的内存,因此会报错。

下面的代码演示了这种情况。

int a = 6;
delete &a; //运行时报错

继续上面的讨论,野指针是指在delete了一个指向动态对象的指针后,没有及时置为NULL,如果对该指针进行解除引用,就会产生垃圾值。

一个铁的纪律,彻底杜绝野指针(这道题没办法,this不能做左值,况且即使改了this,mytest也是改不了的,不再考虑范围)delete了一个指向动态对象的指针后,及时置为NULL。相应的,对指针进行解除引用前,判断指针是否为NULL。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值