[CPP] NULL,nullptr,空指针
NULL和nullptr
首先看看NULL的定义,在C++中,直接定义为0,在C中定义为((void *)0),空指针。因为在C++中需要显示的类型转换int *p = (void *) 0这样会报错,而C可以隐式转换。
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
nullptr是C++11的一个关键字,不是整型也不是指针类型,但是可以转换为任意的指针类型,nullptr的实际类型是std:nullptr_t。所以有以下例子
int i = NULL; // OK
int i = nullptr; // 不能为整型
int* p = NULL; //ok - int转为指针
int* p = nullptr; // ok
nullptr的出现解决了一个容易出现混淆的地方。假设我们有重载的函数
void func(int x);
void func(int* x);
我们想调用func(NULL),实际上我们是想调用void func(int* x),但是因为NULL是0,所以调用了void func(int x),如果是func(nullptr)则调用的是void func(int* x),符合我们的想法,因为nullptr不能转为int,可以转为指针。
所以为了避免风险,如果使用C++11标准,空指针就用nullptr吧。
另外指针定义为空指针,那空指针指向的地址是什么呢?空指针在C/C++中占有特殊的地址,通常它是用来判断一个指针的有效性的。空指针一般定义为0。现代操作系统都
会保留从0开始的一块内存,至于这块内存有多大,视不同的操作系统而定。一旦程序试图访问这块内存,系统就会触发一个异常/信号。操作系统为什么要保留一块内存,而不是仅仅保留一个字节的内存呢?这是因为一般内存管理都是按页进行管理的,根本就无法单纯保留一个字节,而至少要保留一个页面。保留一块内存也有额外的好处,可以检查诸如p=NULL; p[1]之类的内存错误。