【C语言】指针初识(2)——野指针

野指针 

概念:野指针就是指针指向的位置是不可知的(随机的,不正确的,没有明确限制的)

目录

一、野指针成因

1、指针未初始化

2、指针的越界访问

3、指针指向的空间释放

二、 如何规避野指针


一、野指针成因

1、指针未初始化

例:

int main()
{
	int* p;
	*p = 10;
	return 0;
}

        代码中p没有初始化,意味着没有明确指向

        而对于一个局部变量不初始化的话,放的就是随机值

	*p = 10;
	

        此时的p就是野指针(非法访问,当没有初始化时,放入随机值,而*p进行解引用时,通过*p所找到的地址并非是属于我们的)

2、指针的越界访问

int main()
{
	int arr[10] = { 0 };
	int* p = arr;
	int i = 0;
	for (i = 0; i <= 10; i++)
	{
		*(p++) = i;
	}
	return 0;
}

        当i<10时,p还不是野指针

        当i=10时,指针p就超出了数组arr的范围,p就是野指针,用VS编译器运行会出现:

        百度直译过来就是:运行时检查失败2-变量“arr”周围的堆栈已损坏。

 一般报这种错误,都是内存越界,着重检查:

(1)、多维数组初始化是否有误

(2)、数组下标调用是否越界

3、指针指向的空间释放

int* test()
{
	int a = 20;
	return &a;
}
int main()
{
	int* p = test();
	
	printf("%d\n", *p);
	return 0;
}

        在以上代码中,看似没有问题,但是这里的p其实就是一个野指针。为什么这样说呢?

        原因:当我们调用函数test,调用结束后,返回了一个int*的类型,也就是将a的地址返回到调用函数的地方,即赋给了p,值得注意的是,a这个变量是我们在调用函数时,临时创建的一个变量,函数调用完毕,则那一块内存空间就会被销毁掉,所谓销毁就是将相应的空间还给了操作系统。

        这里可能会有人说,不对呀,我运行了,结果是正常的呀,没什么问题的。

        啊啊啊,一定不要这样想啊!我打个比方,你的一个好朋友,她给了你一个地址,你通过这个地址就可以去找到她,但是,你们俩吵架了,她悄悄搬家了,却没有告诉你,你依然通过那个地址可以找到那个地址,但是,房子里面却住了别人。

        而在上述代码中,你之所以还能将a的值打印出来,那是因为你的好朋友虽然和你吵架了,但她还没有找到合适的地方搬走,但此时你再去找她,是不太合适的,换句话讲,你是无法预知打开门的是不是她,充满了不确定性,所以说p为野指针。

        咱们做个测试,因为函数test()的空间已经还给操作系统了,所以我们,再次使用系统中的内存空间,就有可能会影响*p的值

代码:

#include<stdio.h>
int* test()
{
	int a = 20;
	return &a;
}
int* test1()
{
	int b=5;
	return &b;
}
int main()
{
	int* p = test();

	int* p1 = test1();

	printf("%d\n", *p);
	return 0;
}

        在这里,我们在上述代码中,又定义了一个函数test1(),并调用了它一次,而我们还是继续打印*p,注意啊,打印的还是*p,不是*p1,但我们此时来观察输出,如图:

为什么呢?

        因为上述中,我们调用完test(),相应空间就还给操作系统了,也就是说,调用test1()时,test1()会向系统申请一块空间,而操作系统是完全可以将刚才分配给test()的空间再次分配给test1(),所以在test1()中,将其对应的地址内容改变成了5。

        通俗的说,就是你的好朋友20,已经搬走了,5住进去了,你现在再通过旧的地址去找到的房子时,开门的人就是5了。 

二、 如何规避野指针

1、指针初始化

如果有确切的值就给它初始化为相应的值,如果没有,则初始化为NULL

2、小心指针越界

这个问题在自己编写代码时,就需要注意了,因为编译器不会报错

3、指针指向空间释放,则立马将其置为空指针(NULL

4、避免返回局部变量的地址

5、指针使用之前检查其有效性

在使用前判断指针是否为空指针(NULL),因为空指针它不指向任何对象

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙洋静

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值