万恶之源---指针<第二弹>

本文详细解释了野指针的概念,分析了其产生的常见原因,包括指针未初始化、越界访问和指向已释放空间。并提供了规避野指针的方法,如指针初始化、检查边界和及时置NULL等,强调了在使用指针前确保其有效性的必要性。
摘要由CSDN通过智能技术生成

前言

在上一篇文章中,我讲述了有关于内存长啥样,指针是什么,我们为什么需要指针,地址是如何生成的,指针相关的符号及其应用等等,而在今天的文章当中,我们将会讲到在运用指针的时候人们常常会烦的错误---野指针

1.野指针是什么?什么情况下回造成野指针?

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

C语言规定,只有被分配的空间才能使用,而野指针就是会指向一块不属于他的空间,而你非要访问这一块非你的空间,那么此时野指针就会像一只”野狗“一样危险。

那么常见的有哪些情况会造成野指针呢?

1.指针变量未初始化

我们先来看一段错误的代码:

#include<stdio.h>
int main()
{
int *p;//指针变量未初始化,不明确其指向的空间为何处,指向的未知未随机的
*p=10;//调用野指针即构成了非法访问
return 0;
}

注:①局部变量如果不初始化,则其内部储存的值即为随机的,内部只有在为函数开辟栈帧空间时赋的初始值。

②在静态区存储的数据,如全局变量与静态变量其不初始化时,内部储存的值为0(即可以i不初始化)

2.指针越界访问

错误的范例如下:

#include<stdio.h>
int main()
{
ubt arr[5]={0};
int i=0;
int* p=&arr[0];
for(i=0;i<11;i++)//刚指向数组最后一个元素的尾地址时并不违法,但一旦开始方位位于那个地址及其以后的空间后,即为非法访问
{
*(p++);
}
return 0;
}

通常我们看到的这种样式的报错,多半就是数组溢出,非法访问引起的

3.指针指向的空间已经被释放了
#include<stdio.h>
int* test()//返回的为指针类型的数据
{
int n=100;
return &n;
}
int main()
{
int *p=test();
printf("%d\n",*p);
return 0;
}

执行到调用函数语句,即进入函数,为n分配一块空间,除了自定义函数,这块空间就归还给了内存,n的空间就不复存在,即使你用int *p去接受这块空间的地址。

这块空间已经不属于变量n,即使有了地址也无法使用,如果使用即为非法访问。

注:如果在函数调用完以后无其他指令,去开辟(使用)这块函数战阵的话,其实内部储存的还是上次存在里面的n的数据,只不过访问这块空间时为非法访问而已。

2.如何规避野指针? 

既然我们了解了野指针是多么多么的可怕,那么我们怎样才能把这只”野狗“给拴起来呢?

以下为常见的几种规避野指针方法:

1.指针初始化

如果明确知道指针指向哪里就直接赋值地址 ,如果不知道指针应该指向哪里 ,可以给指针赋值NULL.

NULL 是C语言中定义的一个标识符常量 ,值是0 ,0也是地址 ,这个地址是无法直接使用的 ,读写该地址会报错。(相当于就是为指针变量赋初值)

 #ifdef   cplusplus
        #define NULL 0
     #else
        #define NULL ((void *)0)
     #endif

由此可见,NULL就是0. 

注:之后需要用到指针变量的时候在为其赋值,空指针不能访问,只有再为其赋另一个空间的地址才能用。

2.不要然指针越界

一个程序向内存申请了哪些空间 ,通过指针也就只能访问哪些空间 ,不能超出范围访问 ,超出了就是越界访问。

3.指针变量不再使用时 ,及时置NULL ,指针使用之前检查有效性

当指针变量指向一块区域的时候 ,我们可以通过指针访问该区域 后期不再使用这个指针访问空间的 时候 ,我们可以把该指针置为NULL 因为约定俗成的一个规则就是:只要是NULL指针就不去访问, 同时使用指针之前可以判断指针是否为NULL不为空才用)

我们可以把野指针想象成野狗 ,野狗放任不管是非常危险的 ,所以我们可以找一棵树把野狗拴起来, 就相对安全了 ,给指针变量及时赋值为NULL ,其实就类似把野狗栓前来 ,就是把野指针暂时管理起来。

不过野狗即使拴起来我们也要绕着走 ,不能去挑逗野狗 ,有点危险;对于指针也是 ,在使用之前 ,我们也要判断是否为NULL ,看看是不是被拴起来起来的野狗 ,如果是不能直接使用 ,如果不是我们再去使用。

简而言之其实我就只用记住:

不再使用时 未知初始化为什么时,置为空指针。

使用前判断不为野指针再用

(保证使用的空间是自己的)

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

对于在一个函数内部定义的局部变量,那么他被分配的空间其实可以理解为与它拥有一样的作用域,一旦这个函数执行完以后,这个在函数内部定义的局部变量的空间就被回收了,只要你在访问这个局部变量的空间,那你就是非法访问!

当然,其实非法访问的情况还有很多,只要一个指针变量内储存的地址指针指向的位置是不可知的 随机的、不正确的、没有明确限制的),那么此时你就需要先把他置为空指针,或者为它赋值。

创作不易,欢迎点赞,收藏,关注❤~~

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小比特newer

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

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

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

打赏作者

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

抵扣说明:

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

余额充值