野指针(指针闯关4)

目录

1. 什么是野指针

2. 野指针的成因

2.1 指针未初始化

2.2 指针越界访问

2.3 指针指向的空间释放

3. 如何规避野指针

3.1 指针初始化

3.2 小心指针越界

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

3.4 避免返回局部变量的地址


1. 什么是野指针

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

2. 野指针的成因

2.1 指针未初始化

7791afebd9924c4bb60e8d138986b017.png

        上图中的局部变量指针p 未初始化,默认为随机值,也就是说指针p 指向的内存位置是随机的,即 p 是野指针。 

        在编译器为 MSVC 的 vs2022 中,是不能打印输出 未初始化的局部变量的随机值 的。但在编译器为 GCC 的 小熊猫C++ 中可以,且每一次运行打印出的随机值都不同。

ba03e5136e89444eaa93ff2b24cf7a4d.png

e958796cbf5044e89f90e17e3fb65cf6.png

4ac86c59135e451db5b1c9a8684e95b6.png

2.2 指针越界访问

a04f81711df74d3085d2e9fec015eddb.png

        数组arr 的大小为 sz,最后一个元素的下标是 sz - 1。当指针变量p 指向 arr[sz] 时,超出了数组范围,p 就成了野指针。

495826d0cae84b2d8c47c898328639a4.png

2.3 指针指向的空间释放

        作用域(scope)是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效(可用) 的,而限定这个名字的可用性的代码范围就是这个名字的作用域。

        1. 局部变量的作用域是变量所在的局部范围。

        2. 全局变量的作用域是整个工程(项目)。

        生命周期指的是变量的创建(申请内存)到变量的销毁(收回内存)之间的一个时间段。

        1. 局部变量的生命周期是:进入作用域变量创建,生命周期开始;出作用域,生命周期结束。

        2. 全局变量的生命周期是:整个程序的生命周期。

278a5e953a4040f99c89cbc93c032997.png

        按理说,test函数返回变量a 的地址后,内存中 test函数栈帧销毁,变量a 也跟着销毁了,第一次 printf 输出 *p 就应该是随机值,但是却不是随机值,第二次输出才是随机值,我大致了解 函数栈帧的建立和销毁 后,还是不明白,决定不细究它了,要掌握更多指针的重要知识才是!

        推荐以下博客以作简单了解:

        为什么函数可以返回局部变量,但是不能返回局部变量的地址?http://t.csdnimg.cn/utdwO

3. 如何规避野指针

3.1 指针初始化

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

        NULL 是C语言中定义的⼀个标识符常量,值是 0,0 也是地址,这个地址是无法使用的,读写该地址会报错。 

3.2 小心指针越界

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

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

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

if (p != NULL)  // 判断

{

        //...

}

3.4 避免返回局部变量的地址

        如造成野指针的第3个例子,不要返回局部变量的地址

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值