目录
野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
成因1:指针变量没有初始化
#include<stdio.h>
int main()
{
int a = 10, * pc;
*pc = 10;
printf("%d ", *pc);
return 0;
}
pc是一个int类型的指针变量,但是没有被初始化,默认随机值,指向未知空间,pc为野指针。
成因2:指针释放后之后未置空
int main()
{
char* s = (char*)malloc(5);
s = "hello";
free(s);
printf("%s\n", s);
return 0;
}
s指向了动态申请的空间,空间存放hello,动态申请的内存空间被释放,s指向的空间地址不变,但是s指向的空间回归了操作系统,有可能被其他程序使用,s指向空间里面的值发生了变化。
s指向空间不变,但是空间里面的内容可能会改变
成因3:指针操作超越变量作用域
#include<stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int* pc = arr;
for (int i=0;i<11;i++)
{
pc[i] = i;
}
return 0;
}
对arr[10]的错误访问
成因4:指针所指向的变量在指针之前被销毁
#include<stdio.h>
char* fun()
{
char arr[10] = "hi";
return arr;
}
int main()
{
char* p = fun();
printf("%s", p);
return 0;
}
fun函数被调用的时候,栈区存放了局部数组arr,fun返回之后,占用的内存已经被释放掉,此时指针p指向一个被释放掉的栈空间,如果说栈空间值没有被修改,得到预期结果,但是如果修改,p指向的空间内容不可知时,p就变成了一个野指针。
#include<stdio.h>
int * fun()
{
int a = 10;
int *p = &a;
return p;
}
int main()
{
int* s = fun();
printf("hi\n");
printf("%d", *s);
return 0;
}
如果说没有 printf("hi\n");这时候虽然说fun函数被调用的时候,栈区存放了局部变量a,fun返回a的地址之后,占用的内存已经被释放掉,此时s指向一个被释放掉的栈空间,但是释放的空间只是返回给了操作系统,没有被销毁,得到a的值10。
但是有了printf("hi\n");,printf是输入输出函数,fun函数被销毁的空间,由printf开辟的函数栈帧覆盖,把原来a的内存空间覆盖了,这时候s指向的空间里面的值更改为不确定值,打印随机值。
知道了野指针产生的原因,避免方法就出来了,在指针的解引用之前,确保指针指向一个绝对可用的空间。
-
定义指针时,同时初始化为NULL
-
在指针解引用之前,先去判断这个指针是不是NULL
-
动态内存释放完之后,将指针赋值为NULL