概念:
野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
野指针比喻为路上的野狗,没有主人的
野指针成因
1、指针不初始化
TIP:局部变量和全局变量的初始化
局部变量表示在主函数内部创建的变量(在main函数大括号里面创建的变量),局部变量不初始化,就默认是随机值。
而全局变量不初始化,默认是0.
int main() { //这里的p就是野指针 int* p;//p是一个局部的指针变量,局部变量不初始化的话,默认是随机值 *p = 20; return 0; }
这里的底层逻辑就是非法访问内存空间。你必须跟编译器申请自己内存空间,不能随便就访问了一块内存,这就是非法的。比如你入住宾馆,必须申请属于自己的房间入住,不能随便进入一间房间,这就是非法的
2、指针越界访问
当指针指向的范围超出超出数组arr的范围时,指针就是野指针。
int main() { int arr[10] = { 0 }; int* p = arr; for (int i=0;i<=10;i++) { //当指针指向数组外界,此时就变成野指针 *p = i; p+=1; } for (int i=0;i<=9;i++) { printf("%d ", arr[i]); } return 0; }
3、指针指向的空间释放
本来申请的空间被释放了,但指针还记得原地址,在进行访问时 仍会造成非法空间内存访问。
在动态内存开辟是会讲到。
另一种场景:
int* test() { int a = 10; return &a; } int main() { int* p = test(); *p = 20; return 0; }
在自定义函数中创建的变量,出去这个函数体,在函数中创建的变量就会自动销毁(生命周期)。
所以在出test这个函数体后,a所申请的内存空间会自动销毁,而主函数中再次调用这个地址时,就会造成非法内存空间访问,也就是野指针!
如何规避野指针
1、指针初始化
其实一个好的编程习惯就是,不管什么类型的变量你在定义时都要先初始化。
初始化指针的两种方式
(1)、当不知道指针初始化什么类型时,用空指针NULL代替。
(2)、明确初始化的值
int main() { int* p = NULL; int a = 10; int* s = &a; return 0; }
2、自我检查数组是否存在越界情况
因为C语言不能自己检查数组是否越界。
总结:
为了在写代码时尽量规避野指针的出现,我们要做到以下几点。
1、当一个指针不知道指向哪里时,我们将其指向空指针。
2、当那个指针指向的空间释放的时候,将其指向空指针。
3、当指针知道具体指向那个空间,我们就将其指向具体的空间
此时,我们只需要判断指针是否为空指针,是空指针我们根本不需要解引用。是具体的指针我们再进行解引用。