野指针与空指针
本文基于《C++ Primer(第五版)》和网上博文所写,若有错误,欢迎留言指出!
一、空指针
空指针不指向任何对象,在视图使用一个指针之前可以首先检查它是否为空。
定义空指针:
1 int *p1=nullptr; //等价于int *p1=0; 2 int *p2=0; //直接将p2初始化为字母常量0 3 4 /* 要包含#include<cstdlib> */ 5 int *p3=NULL; //等价于int *p3=0;
1、NULL
- NULL不是关键字,而只是一个宏定义。
在C中,习惯将NULL定义为void*指针值0,也可以将NULL定义为整常数0:
1 #define NULL (void*)0
而在C++中,NULL被明确定义为常整数0
1 #define NULL 0
导致不同定义的根本原因是:隐式类型转换(implicit conversion)。C++不支持void*到其他类型的隐式转换。
2、nullptr
C++11新标准中引入nullptr,为什么?-------原因和C++的重载函数有关。
C++通过搜索匹配参数的机制,试图找到最佳匹配(best-match)函数,如果继续支持void*的隐式类型转换,则会带来语义二义性(syntax ambiguous)的问题。如:
1 #include<cstdlib> //C++中使用NULL要包括头文件 2 void func(int) {} // #1 3 void func(char *) {} // #2 4 5 func(NULL); //调用那个版本
虽然函数#2的形参是char *指针,但还是调用函数#1,根本原因是C++中NULL扩展为0,也是常数int。常数0既是整数常量,也是空指针常量。
为了,解决这种二义性,C++11标准引入关键字nullptr,它是一种空指针常量。若第五行为一下代码,则会调用#2.。
1 func(nullptr);
二、野指针
野指针不是空指针,是指向“垃圾”内存(不可用内存)的指针。
野指针的成因主要有三种:
1、指针变量没有被初始化
任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。
2、指针p被free或者delete之后,没有置为NULL(nullptr)。这样做会让人误以为p是个合法的指针。
free和delete只是把指针所指向的内存给释放掉,但并没有把指针本身给清理掉。这时候的指针依然指向原来的位置,只不过这个位置的内存数据已经被销毁。通常会用语句if (p != NULL)进行防错处理。很遗憾,此时if语句起不到防错作用,因为即便p不是NULL指针,它也不指向合法的内存块。所以在指针指向的内存被释放后,应该将指针置为NULL。
3、指针操作超越了变量的作用范围。
1 class A 2 { 3 public: 4 void Func(void){ cout << “Func of class A” << endl; } 5 }; 6 void Test(void) 7 { 8 A *p; 9 { 10 A a; 11 p = &a; // 注意 a 的生命期 ,只在这个程序块中(花括号里面的两行),而不是整个test函数 12 } 13 p->Func(); // p是“野指针” 14 }
Ref:
http://lib.csdn.net/article/c/19307
http://blog.sina.com.cn/s/blog_13f3066b90102w0k1.html(好好看)
http://www.cnblogs.com/fly1988happy/archive/2012/04/16/2452021.html

浙公网安备 33010602011771号