空指针与野指针
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指针也是一个野指针
解决此类野指针问题,我们应该当指针指向的内存被释放时,我们也应该将指针置空
上一篇: 2019最新Java教程免费