@toc

什么是野指针?

概念︰野指针就是指针指向的位置是不可知的(如:随机的、不正确的、没有明确限制的)

说人话就是:野指针是错误的指针引用形式,通常有以下几种情况

  1. 指针未初始化
  2. 越界访问
  3. 指针指向的空间已释放

悬垂指针(dangling pointer):是指在程序中仍然存在,但不再指向有效内存地址的指针。当指针指向的对象被释放或销毁后,指针仍然保留着先前所指向的内存地址,这时指针就成为悬垂指针。

1.指针未初始化

这个概念非常容易理解,同变量一样,指针同样需要我们的初始化

1
2
3
//初始化指针
int a = 10;
int*p = &a;

指针未初始化 通常是以下情况

1
2
3
4
5
int main()
{
int*p;
*p=20;
}

这里的指针并没有指向某个内存地址,即便我们更改它的内容也是无效的

指针会默认赋予一个随机值,属于非法访问内存

当然,编译器遇到这种情况会直接报错

image-20210916212433314

2.越界访问

越界访问的情况通常出现在数组中

1
2
int arr[10]={1,2,3,4,5};
int* p=arr;

我们知道,数组名代表是首元素的地址

我们可以利用 for循环和指针++ 的方式,使指针访问数组中的每个元素

1
2
3
4
5
6
7
8
9
10
11
int main()
{
int arr[5]={1,2,3,4,5};
int* p = arr;
int i =0;
for(i=0;i<=5;i++)
{
*p=0;
p++;
}
}

我们知道,数组中的元素访问都是通过下标的方式。5个元素的数组,下标是从0-4

而在此代码中,p++第五次的时候,下标已经变成了5,对应的是第六个元素

但数组中并没有第六个元素,此时指针访问的就是一个空的地址了

同样属于非法访问

这就是越界访问的一种

3.指针指向的空间已释放

每当我们定义一个变量时,系统都会赋予这个变量一个内存的地址空间

这时候我们把这个地址赋予给指针p,指针便记录下了这个地址

用图来给大家演示一下什么叫指向的空间已释放

image-20210916213548912

代码示例如下

1
2
3
4
5
6
7
8
9
10
11
12
int* test()
{
int a = 10;
return &a;
}

int main()
{
int* p = test();
*p = 20;
return 0;
}

image-20210916214004377


如何避免野指针?

1.指针初始化

在使用指针的时候,我们要像创建变量一样初始化指针

如果不知道把指针初始化为什么,那就赋值为NULL(代表0)

1
2
3
4
5
6
7
8
9
10
11
 1 int main()
2 {
3 //当前不知道p初始化为什么的时候
4 //直接初始化为NULL(空指针-->0)
5 int* p = NULL;
6 //明确知道初始化的值
7 int a = 10;
8 int* ptr = &a;
9
10 return 0;
11 }

2.小心指针越界

在使用指针的时候,我们要注意不能让指针越界

如遇到数组的情况,一定要注意下标和元素个数的区别

  • 注意:C语言本身是不会检查数据的越界行为的!

3.指针指向空间释放就置之为NULL

在我们指针使用完毕之后,为了避免指针指向的空间被系统释放

我们可以将指针初始化为空指针,NULL

4.指针使用之前检查有效性

什么是有效性?

NULL的空指针就是无效的

为了避免我们引用这种无效的空指针,我们可以在使用指针之前用if语句判断一下它是否为空

1
2
if(p!=NULL)
*p=10;

判断为有效指针,我们再使用它

做到以上4点,就能基本避免我们的代码出错。这只能避免,并不能杜绝

“你永远叫不醒一个想写bug的人”


结语

以上就是野指针的基本解释,希望对你有帮助

点个赞再走吧!万分感谢!