欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

空指针与野指针

程序员文章站 2024-01-14 21:29:16
...

1.空类型指针

首先什么是空类型呢,空类型就是void,自然,空类型指针就是void *

2.空类型指针的作用

void * 可以指向任何类型对象的地址,表示这是一个指针,和地址值有关,但不知道存储在此地址上的对象的类型,所以在取空类型指针所指向的值的时候,应将空类型指针转换为对应的指针类型

int a = 10;
char b = 'a';
float c = 12.0;
	
void *pa = &a;
void *pb = &b;
void *pc = &c;

int aa = (int)(*pa);    //错误

运行的话,编译器会提示以下错误:

空指针与野指针

修改:

int aa = *((int*)pa);

里面的括号(int*)表示将空类型指针pa强转为int型指针,外面这个括号还外加一个*号,表示取该int型指针所指向的值

1)空指针支持的操作

a. 与另一个指针比较

b. 向函数传递void *指针

c. 在函数里返回void *指针

d. 给另一个void *指针赋值

2)空指针不支持的操作

a. 不支持解引用,不能获取指向对象的值

b. 不能进行指针运算,比如移位操作

int main()
{
	double a = 3.14;
	double *p1 = &a;
	void *p2 = &a;                 //正确,将一个double型数据的地址赋给一个空类型指针
	void *p3 = p1;                 //正确,将一个double型指针赋给一个空类型指针

	//double b = *p2;              //错误,无法对一个空类型指针解引用
	double d = *((double*)p2);     //正确,先将空类型指针强转为double型指针,然后再解引用
	printf("%f\n", d);

	int array[5] = { 1,2,3,4,5 };
	void *p4 = array;
	//for (int i = 0; i < 5; i++)
	//{
	//	printf("%d  ", *(p4 + i)); //错误,不能对空类型指针进行移位操作
	//}

	for (int i = 0; i < 5; i++)
	{
		printf("%d  ", *((int*)p4 + i));   //正确,先将空类型指针强转为int型指针,然后再解引用
	}
	printf("\n");

	system("pause");
	return 0;
}

 空指针与野指针

3.什么是野指针

指向一个非法的或已销毁的内存的指针

危害:对系统造成不可预知的错误

4.野指针的出现

1)指针变量没有被初始化,它缺省值是随机的,它会乱指一气,例如:

char *p;     //野指针,p的值是随机的
int *pd;
printf("%p\n", pd);

在printf中,打印指针的值用%p

编译器会提示错误:

空指针与野指针

为了避免此类野指针的出现,指针变量在创建的同时应该被初始化,要么将它设置为NULL,要么让它指向合法的内存,例如:

char *p = NULL  //#define NULL 0
char *p = (char*) malloc(100);

malloc的全称是memory allocation,中文叫动态内存分配,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址,当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态的分配内存。malloc函数

因为malloc返回的是一个空类型指针,所以需要强转

2)指针p被free或者delete之后,只是把指针所指的内存释放掉了,没有改变指针的值,此时,p沦落为野指针

这就好比你的亲戚搬家了,你手上还留着他的旧地址

char str1[] = "Hello";
char str2[] = "world";
char *pd = (char*)malloc(100);
strcpy(pd, str1);         //正确,将字符串str1复制到指定的内存中去
printf("%p\n", pd);
printf("%s\n", pd);

free(pd);
if (pd != NULL)
{
	strcpy(pd, str2);    //错误,将字符串str2放到没有经过系统指定的内存中去
}
printf("%p\n", pd);
printf("%s\n", pd);

空指针与野指针

我们发现,1)内存经过free释放后,指针的值并没有被释放,还是指在同样的位置里;2)第一个strcpy复制语句正确,将一个字符串复制到系统分配的内存中去,然后第二个strcpy复制语句虽然得到了正确的结果,但它是极其危险的,因为它将一个字符串复制到一个没有经过系统分配的内存中去了,此时的pd指针也是一个野指针

解决此类野指针问题,我们应该当指针指向的内存被释放时,我们也应该将指针置空