野指针与空指针

本文基于《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、指针操作超越了变量的作用范围。

(a)由于C/C++中指针有++操作,因而在执行该操作的时候,稍有不慎,就容易指针访问越界,访问了一个不该访问的内存,结果程序崩溃;
(b)另一种情况是指针指向一个临时变量的引用,当该变量被释放时,此时的指针就变成了一个野指针,如下:
 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

http://blog.csdn.net/sduwgl/article/details/9048209

posted @ 2017-08-17 10:25  王大咩的图书馆  阅读(463)  评论(0)    收藏  举报