目录
3.3 指针变量不再使用时,及时置NULL,指针使用之前检查有效性
1. 什么是野指针
野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)。
2. 野指针的成因
2.1 指针未初始化
上图中的局部变量指针p 未初始化,默认为随机值,也就是说指针p 指向的内存位置是随机的,即 p 是野指针。
在编译器为 MSVC 的 vs2022 中,是不能打印输出 未初始化的局部变量的随机值 的。但在编译器为 GCC 的 小熊猫C++ 中可以,且每一次运行打印出的随机值都不同。
2.2 指针越界访问
数组arr 的大小为 sz,最后一个元素的下标是 sz - 1。当指针变量p 指向 arr[sz] 时,超出了数组范围,p 就成了野指针。
2.3 指针指向的空间释放
作用域(scope)是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效(可用) 的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
1. 局部变量的作用域是变量所在的局部范围。
2. 全局变量的作用域是整个工程(项目)。
生命周期指的是变量的创建(申请内存)到变量的销毁(收回内存)之间的一个时间段。
1. 局部变量的生命周期是:进入作用域变量创建,生命周期开始;出作用域,生命周期结束。
2. 全局变量的生命周期是:整个程序的生命周期。
按理说,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个例子,不要返回局部变量的地址。