在上一节的内容中,我们学习了指针数组、数组指针和函数指针数组
的相关使用,较为重要,大家可以好好理解和掌握,今天我们将学习指针运算
和野指针
。
话不多说,开整!!!
我们到现在为止,应该已经很清楚这样一件事:指针本质上是一种特殊的变量
,用来存储数据的地址
,因此,其也可以进行计算,那么指针之间的运算代表着什么呢,我们来进行验证。
首先我们定义一个数组arr,然后将其首元素地址赋值给指针p,再将p+3赋值给指针变量p1,如下:
int arr[] = {1,2,3,4,56,7};
int* p = arr;
int* p1 = p+3;
那么此时指针p、指针p1与数组间的关系图如下所示:
那么此时两个指针之间的差是什么呢,我们进行打印,如下所示:
#include
int main()
{
int arr[] = {1,2,3,4,56,7};
int* p = arr;
int* p1 = p+3;
printf("%d\n",p1 - p);
return 0;
}
编译查看结果:
可以看到结果为3,而从指针p到指针p1之间正好是3个元素,那么是不是二者之差就代表着两个指针间的元素个数是多少呢,我们再次打印其他的两个指针之差如下:
#include
int main()
{
int arr[] = {1,2,3,4,56,7};
int* p = arr;
int* p1 = p+3;
int* p2 = p+5;
printf("%d\n",p1 - p);
printf("%d\n",p2 - p);
return 0;
}
编译运行,发现结果如下为:
而从指针p到指针p2也是5个元素,因此上述结论不是偶然:
指针 - 指针为两个指针间的元素的个数
当然了,指针不仅可以进行加法运算,同样可以进行加法运算,或者比较大小,不在此处进行验证。
我们都知道,正常来说,每一个指针都应该指向一个地址
,那么如果指针没有指向某个地址
,而是随机指向了一个地址
,那么就产生了野指针
,因此,所谓的野指针:
也就是指针指向的位置随机
在程序的编写过程中,我们要避免野指针的出现,为什么呢?
因为野指针指向的位置是随机的,在后续对指针进行操作时极有可能产生严重的错误,那么究竟什么时候会产生野指针呢,下面进行介绍。
当我们定义了一个指针变量,但并未对其进行初始化,如下:
int* p ;
此时该指针变量p就指向了一个随机地址,后续假设我们要修改指针所指向的地址的值时,就会发生错误,如下代码:
#include
int main()
{
int* p ;
*p = 20;
return 0;
}
当然了,这部分在vscode
中编译不会出现错误,只是会提示指针变量p没有初始化,我们在Linux
下编译可以看到如下结果:
因此,
未被初始化的指针将会变成野指针
第二种情况是:野指针会出现在越界访问时
,比如说数组只有6个元素,那么其下标就是0-5,如果此时我访问下标为6的数组,将其值置9,也会出现野指针,代码如下:
#include
int main()
{
int arr[6] = {0} ;
int i = 0;
for(i=0;i<7;i++)
{
arr[i] = 9;
}
return 0;
}
同样在vscode
中也没有警告,因此在Linux
下演示,结果如下:
因此,
数组越界访问会产生野指针
在自定义的函数中所使用的变量
,其只是一个局部变量
,当跳出函数时,该变量就自动销毁
,因此,如果在代码中返回了一个已经自动销毁的变量,也会产生野指针,如下代码所示:
#include
int* test()
{
int a = 20;
return &a;
}
int main()
{
int* b = test();
printf("%p\n",b);
return 0;
}
同样在Linux
下进行演示,结果如下:
提示我们返回了一个局部变量的地址,编译查看结果:
查看百度,可以知道nil代表着在变量使用前并未被赋值
,因此:
空间释放也会产生野指针
所以说,在使用和定义指针时一定要避免上述情况的发生,尽量进行初始化
,如果实在不知道初始化什么,那么就初始化为空指针NULL
上述内容即使今天的全部内容了,感谢大家的观看。
如果方便,辛苦大家点个赞和关注哦!
您的点赞或评论或关注是对我最大的肯定,谢谢大家!!!