本文借鉴与:百度百科
首先说明一点:
指向非法的内存地址(垃圾内存的地址),那么这个指针就是悬挂指针,也叫野指针,意为无法正常使用的指针。
野指针(悬挂指针):
野指针是指向不可用内存区域的指针(非法内存,垃圾内存)。野指针不是NULL指针,是指向“垃圾”内存的指针。人们一般不会错用NULL指针,因为if语句能够判断。但是野指针是很危险的,if不能判断一个指针是正常指针还是野指针。
野指针的成因主要有3种:
1、指针变量没有被初始化。 任何指针(全局指针变量除外,全局指针变量为NULL)变量在刚被创建的时候不会自动成为NULL指针,它的缺省值是随机的。所以指针变量在创建的时候,要么设置为NULL,要么指向合法的内存。
int *p;
2、指针p被free/delete之后,没有置为NULL(最好加一句p = NULL;),经常性的我们会以为p是个合法的指针。他们只是把指针指向的内存给释放掉,并没有把指针本身干掉,此时指针指向的就是“垃圾”内存。所以我们应该在释放完之后,立即将指针置为NULL,防止出现乱指的情况
#include <iostream> #include <cstring> using namespace std; int main() { char *str = new char[100]; delete[] str; strcpy(str,"nihao"); cout<<str<<endl; return 0; }
运行结果:
nihao
#include <iostream> using namespace std; int main() { int *p = NULL; p = new int; cout<<*p<<endl; delete p; *p = 4; cout<<*p<<endl; return 0; }
4063608
4
linux(编译连接没有错误,没有警告):
0
4
可能有不少人会注意到我们明明已经释放掉了内存了,为什么还能正确的运行呢??空间不是已经被delete掉了吗??
我们是已经释放掉内存了,但是并不影响我们往指向的内存空间中放新的东西
但是这样是特别危险的,我们现在往该内存中放的东西,下次系统在将改内存空间分配给其他变量的时候,这是就产生了一个值,直接影响我们程序的后序操作,所以一般情况下,不建议这样,应该在释放完之后就将其置为NULL
3、指针操作超越了变量的作用范围。不要返回指向栈内存的指针或引用,因为栈内存在函数结束时会被释放。也就是说指向的对象的声明周期已经结束了,然而我们还使用该指针访问该对象
#include <iostream> using namespace std; int * ret() { int num = 10; return # } int main() { int *p = NULL; p =ret(); cout<<&p<<endl; cout<<*p<<endl; return 0; }
(dev-C++)会产生一个警告:[Warning] address of local variable 'num' returned [-Wreturn-local-addr]
运行结果:
0x22fedc
30
0x22fedc(存储指针p的地址),30(返回的并不是我们想象中的10,因为变量num是存储在栈空间的局部变量,当函数执行完后,那么为其中变量所分配的栈空间也就释放掉),所以输出的就是一个不确定的值了。
(LInux):产生一个警告:warning :address of local variable ‘num’ returned
运行结果:
0x7fff37917408
32557
#include <iostream> #include <cstring> using namespace std; int main() { int *p; cout<<p<<endl; return 0; }
window:运行结果:
40d4fb
Linux: 运行结果:
0
所以:我们应该大胆的推测:linux下,int型指针的默认是NULL,而window下,是随机的,一般是指向垃圾内存的