野指针,空指针,失效指针

本文详细介绍了C++和C语言中的野指针、空指针和失效指针的概念。野指针是指未初始化的指针,可能指向任意地址;空指针在定义时初始化为`nullptr`,是安全的指针状态。在C++中,推荐使用`nullptr`而非`NULL`以避免二义性。失效指针通常发生在释放内存或关闭资源后仍继续使用指针,可能导致错误或不可预知的行为。文章通过示例强调了在函数中返回局部变量指针的风险,并指出只有在特定情况下才能安全地这样做。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.野指针和空指针

把这两个放在一起,是因为这个实在是没有什么重要的知识点,还是先看一下吧。

int main()
{
    int *p;
    int *p1=nullptr;
    return 0;
}

指针p为野指针,也就是说在定义一个指针时没有初始化为nullptr,那么这个指针会指向一个随机地址,这就是野指针,野指针是非常危险的。

p1在我们定义的时候初始化为空,p1就是一个空指针。

注意我这里用的是nullptr,不是NULL,nullptr在C++中是专门为了初始化或赋值一个指针为空时用的关键字,为什么不用NULL呢?这里简单说一下,本专栏后期会专门有一期文章介绍C++中nullptr。

在C语言编译器中,NULL的定义为#define NULL 0或者#define NULL  (void*)0;NULL是根据宏定义的字面常量0或者无类型指针0常量,那么这种情况有时候会导致二义性,这里就不举例子了,后期文章可以仔细去看一下,为了解决这种情况,在C11中标准中,处于兼容性的考虑,字面常量0的二义性并没有消除,但标准还是为二义性给出了新的答案,就是nullptr(一个所谓“指针空值类型”的常量)。

2.失效指针

失效指针是本章的一个重点,那么什么是失效指针呢?我们来举例说明:

 int main()
{
    int *r=(int *)malloc(sizeof(int));
    *r=100;
    free(r);
    r=nullptr;
    return 0;
}

free完之后,我们的指针r就是一个失效指针,此时我们再通过r去访问malloc申请来的空间,就会报错,因为free之后,说明我们的指针r和堆区已经没有关系了,但是我们的指针r还是指向堆区的那块空间,所以为了安全起见,我们free完之后,都会将指针置为空。

同理,还有哪些情况是类似于free之后变成了失效指针的情况呢?比如文件的打开和关闭,fclose()。

接下来看这种情况:

int *fun()
{
    int a=10;
    return &a;
}

乍一看,感觉这个代码没什么问题,其实是有很大的安全问题的,我们现在再主函数中调用一下。

int main()
{
	int* p = fun();
	printf("%d", *p);
	return 0;
}

结果:

 

 这不是很正确嘛?我们再来加一段代码

int* fun()
{
	int a = 10;
	return &a;
}
void arr()
{
	int brr[100] = { 0 };
}
int main()
{
	int* p = fun();
	arr();
	printf("%d", *p);
	return 0;
}

 在调用完fun函数时,再调用一下arr函数,此时的结果确变成了0;

这是因为调用fun函数时,栈需要给fun函数开辟栈帧,里面存放变量a,值为10,等fun函数结束后这部分栈需要归还系统,在主函数调用后打印出来的只不过是残留值 ,指针p还指向原来变量a的地址,当我们调用arr函数后,arr栈帧里面有brr这个数组,大小为100个,值全为0,brr会把原来的残留值冲洗掉,再打印时发现p指向的地址空间被冲洗掉成立0。

所以我们不可以轻易将函数中的局部变量以指针或引用方式返回。

以下这三种情况才可以:

int g_max=0;//全局变量可以以指针返回
int *fun(int *p)
{
    static int a=10;//静态局部变量可以以指针返回
    retunr p;//函形参是一个指针可以以指针返回
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值