前言
在上一篇文章中,我讲述了有关于内存长啥样,指针是什么,我们为什么需要指针,地址是如何生成的,指针相关的符号及其应用等等,而在今天的文章当中,我们将会讲到在运用指针的时候人们常常会烦的错误---野指针
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.避免返回局部变量的地址
对于在一个函数内部定义的局部变量,那么他被分配的空间其实可以理解为与它拥有一样的作用域,一旦这个函数执行完以后,这个在函数内部定义的局部变量的空间就被回收了,只要你在访问这个局部变量的空间,那你就是非法访问!
当然,其实非法访问的情况还有很多,只要一个指针变量内储存的地址指针指向的位置是不可知的( 随机的、不正确的、没有明确限制的),那么此时你就需要先把他置为空指针,或者为它赋值。
创作不易,欢迎点赞,收藏,关注❤~~