您的位置:首页 > 职场人生

面试-野指针,悬挂指针

2016-03-27 11:27 375 查看
本文借鉴与:百度百科

首先说明一点:
指向非法的内存地址(垃圾内存的地址),那么这个指针就是悬挂指针,也叫野指针,意为无法正常使用的指针。

野指针(悬挂指针)

野指针是指向不可用内存区域的指针(非法内存,垃圾内存)。野指针不是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

可以看到我们的delete释放掉了在堆区分配的空间之后,指向的内容就已经不可知

#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;
}

dev-c++(编译连接没有错误,没有警告):

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下,是随机的,一般是指向垃圾内存的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: