野指针,是看上去指向合法内存,实际该内存已经释放;或未初始化的指针。
"野指针"的成因主要有3种:
(1)指针变量未被初始化。任何指针变量被创建时不会自动成为NULL指针,它的缺省值为随机。
指针变量在创建的同时必须被初始化。
char *p = NULL; //将指针设置为NULL
char *str = new char(100); //将指针指向定义变量
(2)指针p被free(释放)或者delete(删除)之后,没有置为NULL;
当指针没有使用价值时,记得释放,释放成功后记得为该指针赋值NULL。
if(NULL != p) //检验使用完指针后,释放该指针所指向的内存。
{
delete p;
p = NULL;
}
(3)指针操作越出变量的作用范围:
class A
{
public:
void Func(void)
{
printf("Func of class A\n");
}
};
void Test(void)
{
A *p;
if (...)
{
A a;
p = &a; //a的生命周期在if内
}
p->Func(); //p未被初始化
}
(4)可以使用引用替代指针:
引用具有指针的功能,同时具有普通变量的功能。引用的变量必须真实存在。引用作为函数的输入参数比指针更直接的效果。
void swap(int *p1, int *p2) //指针实现两数交换
{
int tmp = 0;
tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
void swap(int &p1, int &p2) //引用实现两数交换
{
int tmp = 0;
tmp = p1;
p1 = p2;
p2 = tmp;
}
5)使用智能指针:
如果不同对象都需要访问堆上的同一份指针,智能指针可以有效地避免野指针。用智能指针(推荐shared_ptr)进行包装,不同对象可拥有智能指针包装后的指针,每次存取之前使用智能指针的方法_Expired进行指针的有效性检查,如果失败,则表明该对象已经被释放。