野指针:
利用指针你可以将数据写入内存中的任意位置,但是,一旦你的程序中有一个野指针("wild"pointer),即指向一个错误位置的指针,你的数据就危险了-存放在堆中的数据可能会被破坏,用来管理堆的数据结构也可能会被破坏,甚至操作系统的数据也可能会被修改,有时,上述三种破坏情况会同时发生。
注意:"野指针"不是NULL指针,是指向被释放的或者访问受限内存的指针。
人们一般不会错用NULL指针,因为用if语句很容易判断。但是"野指针"是很危险的,if语句对它不起作用。
野指针的成因主要有三种:
指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。例如
char *ip = NULL;
char *ip = new char;
一、 指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针。别看free和 delete的名字(尤其是delete),它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉。此时指针指向的就是"垃圾"内存。释放后的指针 应立即将指针置为NULL,防止产生"野指针".
例:free(p);
if (p);
p=NULL;
二、指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针。别看free和 delete的名字(尤其是delete),它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉。此时指针指向的就是"垃圾"内存。释放后的指针 应立即将指针置为NULL,防止产生"野指针".
例:free(p);
if (p);
p=NULL;
三, 指针操作超越了变量的作用范围。比如不要返回指向栈内存的指针或引用,因为栈内存在函数结束时会被释放。示例程序如下:
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()时,p 的值还是 a 的地址,对象 a 的内容已经被清除,所以 p 就成了"野指针" .