空指针
空指针就是 void*;
void* 可以指向任何类型对象的地址,表示这是一个指针,和地址值无关,但不知道存储在该地址上的数据类型,所以在获取该指针所指向的值时,应将其转换为对应的指针类型
int a=10;
void* pa=&a;
int b=*((int*)pa); //强转为 int*
空指针支持的操作:
1、向函数传递 void指针
2、在函数里返回 void 指针
3、在别的 void* 赋值
空指针不支持的操作:
1、不支持解引用
2、不支持指针运算
野指针
野指针指向了一块随机的内存空间,不受程序控制。比如指针指向已经被删除的对象或者指向一块没有访问权限的内存空间,之后再对其解引用,就会出现问题。
产生原因:
1、指针定义时未初始化:除了static修饰的指针变量外,其他任何指针变量都不会被置为空,默认都是随机的;
2、指针被释放时没有置空:在使用malloc开辟内存时,返回值为空,则开辟失败,若不为空,在开辟成功,指针指向空间首地址。该空间在释放后,如果未及时对指针置空或者其他赋值操作,就会变成一个野指针。
3、指针操作超越变量作用域:不要返回指向栈内存的指针或者引用,因为栈内存在函数结束时会被释放。
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 是“野指针”
}
};
危害:
野指针的问题在于,指针指向的内存已经无效了,而指针没有被置空,解引用一个非空的无效的指针是一个未定义行为,并且野指针很难去定位出错的地方,不好修改程序。
规避方法:
初始化时将其置为NULL,释放时也将其置为NULL,
悬空指针
悬空指针是指指针最初指向的内存已经被释放了的一种指针。