c语言--空指针和野指针

本文详细介绍了C语言中指针的概念,包括不同类型指针的声明,野指针的形成原因(未初始化、越界访问和空间释放),以及如何通过初始化、检查边界和置NULL来规避野指针。还强调了空指针(NULL)的区别和正确使用方法。
摘要由CSDN通过智能技术生成

一、指针简介

指针很灵活,它可以指向任意类型的数据。指针的类型说明了它所指向地址空间的内存,以下是有效的指针声明:

int    *p;    /* 一个整型的指针 */
double *p;    /* 一个 double 型的指针 */
float  *p;    /* 一个浮点型的指针 */
char   *p;    /* 一个字符型的指针 */

二、野指针

概念

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

成因

1.指针未初始化

#include<stdio.h>
int main()
{
	int* p;//局部变量指针未初始化,默认为随机值
	*p = 20;
	return 0;
}

2.指针越界访问

#include<stdio.h>
int main()
{
	int arr[10] = { 0 };
	int* p = &arr[0];//p此时不是野指针
	int i = 0;
	for (i = 0; i <= 11; i++)
	{
		        //当指针指向的范围超出数组arr的范围时,p就是野指针
		*(p++) = i;
	}
	return 0;
}

在这里插入图片描述

运行结果:
在这里插入图片描述
这就是指针越界访问了后的结果。

3.指针指向的空间释放

#include<stdio.h>
int* test()
{
	int a = 0;
	return &a;
}
int main()
{
	int* p = test();
	printf("%d\n", *p);
	return 0;
}

在这里插入图片描述
这就是非法访问了。

如何规避野指针

1.指针初始化

1.如果明确知道指针指向哪⾥就直接赋值地址,如果不知道指针应该指向哪⾥,可以给初始化一个明确的地址。2.如果现在还不知道应该指向哪里,就初始化为NULL。
例如:

#include<stdio.h>
int main()
{
	int a = 10;
	int* p = &a;//1.明确知道指针指向哪里
	int* p2 = NULL;//不明确指针指向哪里
	return 0;
}

2. 小心指针越界

一个程序向内存申请了哪些空间,通过指针也就只能访问哪些空间,不能超出范围访问,超出了就是
越界访问。如上面那个代码的解释。

#include<stdio.h>
int main()
{
	int arr[10] = { 0 };
	int* p = &arr[0];//p此时不是野指针
	int i = 0;
	for (i = 0; i <= 11; i++)
	{
		        //当指针指向的范围超出数组arr的范围时,p就是野指针
		*(p++) = i;
	}
	return 0;

3.指针变量不再使⽤时,及时置NULL,指针使⽤之前检查有效性免返回局部变量的地址

当指针变量指向⼀块区域的时候,我们可以通过指针访问该区域,后期不再使⽤这个指针访问空间的时候,我们可以把该指针置为NULL。因为约定俗成的⼀个规则就是:只要是NULL指针就不去访问,同时使⽤指针之前可以判断指针是否为NULL。我们可以把野指针想象成野狗,野狗放任不管是⾮常危险的,所以我们可以找⼀棵树把野狗拴起来,就相对安全了,给指针变量及时赋值为NULL,其实就类似把野狗栓前来,就是把野指针暂时管理起来。不过野狗即使拴起来我们也要绕着⾛,不能去挑逗野狗,有点危险;对于指针也是,在使⽤之前,我们也要判断是否为NULL,看看是不是被拴起来起来的野狗,如果是不能直接使⽤,如果不是我们再去使⽤。

4.避免返回局部变量的地址

不要返回局部变量的地址(解释如上图)

#include<stdio.h>
int* test()
{
	int a = 0;
	return &a;
}
int main()
{
	int* p = test();
	printf("%d\n", *p);
	return 0;
}

三、空指针(NULL)

在 C 语言中,如果一个指针不指向任何数据,我们就称之为 空指针 ,用 NULL 表示。例如:

int *p = NULL;

注意区分大小写,null 没有任何特殊含义,只是一个普通的标识符。NULL 是一个宏定义,在 stdio.h 被定义为:

#define NULL ((void *)0)

我们知道,变量一旦定义就要分配内存,指针变量也是如此。例如:

int *p;  //它不是空指针,这个是为初始化

它的值是随机的,是垃圾值,如果不小心使用了它,运行时一般会引起段错误,导致程序退出,甚至会不知不觉地修改数据。p 经过定义,就一定在内存中分配了 4 个字节的空间,只是它的值是随机的,不像 int 会被初始化为 0,但是它确实指向了一段正常使用的内存。使用 p 时,操作的就是这段内存的数据,幸运的话能够正常运行,不过大部分情况下这段内存是无权操作。

NULL 和 0

不要把 NULL 和 0 等同起来,下面的写法也是不对的:

int *p = 0;

正确的书写:

int *p = NULL;

在这里插入图片描述
欧耶!!!!!!!我学会啦!!!!!!!

  • 32
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值