c语言入门-野指针

目录

成因1:指针变量没有初始化

成因2:指针释放后之后未置空

成因3:指针操作超越变量作用域

成因4:指针所指向的变量在指针之前被销毁


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

成因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指向的空间里面的值更改为不确定值,打印随机值。

知道了野指针产生的原因,避免方法就出来了,在指针的解引用之前,确保指针指向一个绝对可用的空间。

  1. 定义指针时,同时初始化为NULL

  2. 在指针解引用之前,先去判断这个指针是不是NULL

  3. 动态内存释放完之后,将指针赋值为NULL

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值