空指针
任何对象和函数的地址都不可能是空指针,因为空指针没有指向任何的对象或者函数。
空指针赋值分区
进程地址空间从0x00000000到0x0000FFFF的闭区间,保留着一分区的目的是帮忙捕获对空指针的复制,如果进程中的线程试图读取或写入这一分区内的内存地址,就会引发访问违规。
当使用malloc无法分配足够的内存,会返回NULL,如果没有进行检测,则直接进行访问,会引发内存访问违规导致程序终止。
(new分配内存失败会抛出异常,也可以通过(std::nothrow不抛异常,而是返回NULL,有些老的编译器new失败后,也不会抛异常,这种情况另外分析,不在这做说明)
空指针对象调用成员函数时,程序会发生崩溃
因为程序中的数据都需要从物理地址中读取或写入,一个有效的指针的逻辑地址可以映射到物理地址上,所以可以访问成功。
空指针的逻辑地址并没有映射到物理地址上,当访问时,就会产生访问违规。(根据Windows核心编程第13章:Windows内存体系结构)
空指针校验
校验是否为空指针时,建议使用
if(p != nullptr)
不建议使用
if(p != NULL) 或者 if(p)
NULL与nullptr的区别
在C中NULL 是 (void *)0 的指针常量。
在C++中NULL 是一个宏定义 #define NULL 0 ,因为C++不允许将(void *)隐式转换为其它类型。
所以在C++11中出了nullptr,类型为std::nullptr_t,空指针常量可以隐式转换为其它类型,用来区分0与NULL的区别。
例如:
void fun(int i)
{
cout<<"1"<<endl;
}
void fun2(char* p)
{
cout<<2<<endl;
}
int main()
{
fun(NULL); //输出1
fun(nullptr); //输出2
}
野指针
指向一个垃圾内存的指针,不是一个空指针。
出现的情况:
1)、指针没有初始化。
2)、使用delete或free释放了内存,但是指针为赋nullptr或NULL,推荐使用nullptr。(C++11中出了智能指针,自动释放)
3)、指针指向了一个临时变量,当变量释放后,指针成为了野指针。
4)、指针越界访问,因为存在++情况,在执行该操作值,容易存在越界访问,访问不存在的内存,导致崩溃。
若有错误,欢迎各位大佬指出。