面试-野指针,悬挂指针

11 篇文章 2 订阅

本文借鉴与:百度百科

首先说明一点:

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


野指针(悬挂指针)

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

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下,是随机的,一般是指向垃圾内存的


  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值