【C初阶】野指针
文章目录
三、野指针
3.1 介绍
概念:野指针就是指针指向的地址是不可知的(随机的、不正确的、没有明确限制的)。
3.2 野指针成因
-
指针变量未初始化
-
指针的越界访问
-
指针指向的空间被释放( 比如:返回局部变量的地址 )
3.2.1 指针变量未初始化
代码示例:
#include<stdio.h>
int main()
{
//指针未初始化
int* p;//局部变量未初始化,默认为随机值
*p = 20;//使用了未初始化的指针变量
return 0;
}
解释说明:
1 指针变量也是变量,局部变量未初始化,默认为随机值。
2 对随机地址进行解引用操作,就会导致野指针问题。
3.2.2 指针的越界访问
代码示例:
#include<stdio.h>
int main()
{
//指针越界访问
int arr[10] = { 0 };
int* p = arr;
int i = 0;
for (i = 0; i <= 11; i++)//i:0 ~ 11
{
*(p++) = i;
}//Stack around the variable 'arr' was corrupted.
return 0;
}
解释说明:
1 当 i
为10和11时,解引用指针变量会访问数组以外的地址,造成了指针越界访问。
3.2.3 指针指向的空间被释放(返回局部变量的地址)
代码示例:
#include<stdio.h>
int* test()
{
int count = 0;
count++;
return &count;//返回局部变量的地址
}
int main()
{
//返回局部变量的地址
int* p = test();
printf("%d\n", *p);//1
printf("%d\n", *p);//12264882
printf("%d\n", *p);//12264882
return 0;
}
解释说明:
1 返回局部变量的地址,在函数调用结束后,局部变量就会被销毁(收回内存资源);此时返回局部变量的的地址就会导致野指针的问题。
2 第一次解引用时编译器会给出正确值,留了一些“余地”,但再次解引用时会导致野指针。
3 不要返回局部变量的地址。
3.3 如何规避野指针
3.3.1 避免方法
1.指针变量要初始化( 至少在使用指针之前,必须先用已分配的地址初始化它 )
2.小心指针的越界访问
3.指针指向的空间被释放,要及时置空(NULL)
4.避免返回局部变量的地址
5.指针在使用之前(解引用前),要检查指针的有效性
3.3.2 示例
代码示例:
#include<stdio.h>
int main()
{
//如何避免野指针的出现?
int* p = NULL;//指针用NULL进行初始化
int a = 10;
p = &a;
if (p != NULL)//检查指针的有效性
{
*p = 20;
}
return 0;
}
解释说明:
1 指针变量可以使用 NULL
来初始化,也可以使用 NULL
来表示指针置空。
2 int* p = NULL;
p
相当于是一个空指针,没有指向有效空间。
此时该指针是一个空指针,不能直接使用,因为它没有指向任何有效的空间,只是用来说明存在一个指针变量。
在C语言中,NULL
表示 ((void*)0)
:
#define NULL ((void*)0)
3 if (p != NULL) { *p = 20; }
在使用指针变量之前,先检查该指针是否是空指针。( 没有指向有效空间就不再使用该指针 )
p
不为空指针时再使用,但是使用该判断部分的指针 p
必须提前初始化。
总结:
本节介绍了什么是野指针以及野指针的产生原因;给出了如何规避野指针的几种避免方法。
感谢您的阅读!如有任何错误,欢迎您的批评指正!