空指针
空指针不指向任何实际的对象或者函数。反过来说,任何对象或者函数的地址都不可能是空指针。
例如, int p = 0;
不能对空指针进行 操作
野指针
野指针不是空指针,是一个指向垃圾内存的指针。
野指针形成原因:
- 声明指针变量的时候没有初始化
- 指针被free或者delete之后,没有设置为NULL,让人误以为这是一个合法指针。free和delete只是把指针所指向的内存给释放掉,但并没有把指针本身给清理掉。这时候的指针依然指向原来的位置,只不过这个位置的内存数据已经被毁尸灭迹,此时的这个指针指向的内存就是一个垃圾内存。但是此时的指针由于并不是一个NULL指针(在没有置为NULL的前提下),在做如下指针校验的时候
- 指针操作超越了变量的作用范围。由于C/C++中指针有++操作,因而在执行该操作的时候,稍有不慎,就容易指针访问越界,访问了一个不该访问的内存,结果程序崩溃另一种情况是指针指向一个临时变量的引用,当该变量被释放时,此时的指针就变成了一个野指针,如下
使用指针需要注意的地方
(1) 声明指针的时候为空指针。
在函数内部可以通过判断来确定一个指针是否是空指针,从而避免异常的操作,但是并没有办法判断野指针。所以在使用的时候要避免野指针。
int main() {
int* p; //野指针
int* p1 = 0 ; //空指针
}
在使用指针之前可以先先判断检查,是否为空指针。
int main() {
int* p = 0; //空指针
if(p) {
cout<<"you can user * operation";
} else {
cout<<"this is null point";
}
}
运行上面的代码会输出 this is null point
但是如果使用野指针,那么在程序中就没办法判断了。
int main() {
int* p; //空指针
if(p) {
cout<<"you can user * operation"; //会执行这一句
} else {
cout<<"this is null point";
}
}
(2)防止使用指针的时候出现数组越界的异常。
int main() {
int arr[4] = {1,2,3,4};
int* p = arr;
p = p+4;
cout << *p;
}
在上面的代码中就出现了数组越界的情况。这个时候在程序中会有巨大的隐患,要注意避免。
(3)防止出现指针所指向地址失效的情况。
using namespace std;
int a = 188;
int* test() {
return &a;
}
int main() {
int* p = test();
cout <<*p;
}
这个时候并没有能够正常的输出188。因为变量a在程序运行的声明周期之内一直都在内存之中,所以这个时候访问是没有问题的。
但是代码改成下面这个样子就有问题了
using namespace std;
int* test() {
int a = 188;
return &a;
}
int main() {
int* p = test();
cout <<*p;
}
这个时候p指向的是一个临时变量,这个时候可能会形成野指针。
[注] 文章关于野指针的说明部分引用了博客