一、什么是野指针
野指针是指向不可用内存区域的指针
二、如何产生野指针
(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。