在C/C++中的标准定义:c++
#ifdef __cplusplus //条件编译,判断是c++仍是c环境
#define NULL 0 //c++环境
#else
#define NULL ((void *)0) //c语言环境
#endif
#endif
在c语言中的NULL就被替换成了((void *)0),这个总体表示的是一个指针,便是指向0地址的viod类型的指针。安全
因此咱们能够理解为NULL的本质就是0,这个0要看作地址,便是0x00000000。编码
NULL为何出现,就得明白什么是野指针了。spa
注:虽然C标准没有说空指针与指向内存地址0的指针相同,可是分析以后是能够这样理解的。(NULL又称为空指针常量) 指针
又叫迷途指针,即指针指向的地址是随机的。(不指向任何合法的对象的指针)code
指针变量在定义后,不去初始化。这个时候,值就是随机的。这时候这个指针变量就是野指针。对象
好比在栈里定义了一个指针变量,即栈给这个指针变量分配了一个内存,而这个内存里存的值就是该指针指向的地址,然而栈是脏的(反复使用,不擦除),并不知道地址里存的什么数,也就不知道指针指向了哪里。 blog
指针变量在定义后,不去初始化,这个时候,值就是随机的,即指向了随机的一段内存。咱们再去解引用时,就是去访问一个随机地址,那么会有什么样的后果也是未知的。内存
通常有三种状况:字符串
①指向了不可访问的地址(系统不容许访问的地方)
这种状况是最好的,由于程序会报段错误,没法执行。
②指向了可用的,暂时没有用到的地方(譬如程序没有用到的堆栈地址)
这种状况运行时没问题,也不会报错。可是实际上程序是有问题的,假如以后程序因为野指针出现了bug,就死活找不到缘由了。
③指向了可用的,而且是程序中正在被使用的地方
这种状况野指针的解引用可能就会致使指向的那段内存的值被修改,出现一些离奇的错误,致使程序崩溃,数据破坏,损坏。
第一种状况就是
(不可访问的地址)大型商队保镖太强,山贼(野指针)正准备抢劫就被干掉了,并向后面(咱们)的商队发出了警告
第二种状况就是
(能够访问,暂时没用使用的地址)小型商队,山贼就直接抢了,暂时并不影响绕路的咱们。
第三种状况就是
(程序正在使用)咱们的商队,山贼可能抢的可能咱们无法活下去(程序崩溃)
在指针的解引用以前,必定确保指针指向一个绝对可用的空间。
这时候NULL出现的很及时,常规作法
①定义指针后,将指针初始化为NULL。
②指针使用以前绑定一个可用地址。
③在指针解引用前,去判断是否为NULL。
④使用完,后赋值为NULL。
1 int a = 1; 2 int *p = NULL; //定义指针并初始化为NULL
3 p = &a; //绑定一个可用地址
4
5 if (NULL != p) //判断是否不等于NULL
6 { 7 *p = 10; //解引用
8 } 9
10 p = NULL; //使用完,从新赋值为NULL
注意(小技巧):
通常将判断指针是否相等时,不写成if (p == NULL),而写成if (NULL == p),缘由是== 与 = 的误错,程序的意思会不同。等号少写后,if (p = NULL)不会报错,if (NULL = p)会报错。
①让野指针指向一个 '安全的0地址处'
大部分cpu中,内存0地址处不能随便访问的,因此避免野指针的误伤,指向0地址后的使用就会报段错误。帮助咱们找错误。
②特殊标记,即增长程序的可读性。
表示指针是个野指针。
①'\0'是个转义字符,ASCII编码值是0,本质就是0.
'\0'用法是C语言字符串的结尾标志
②'0'是个字符,ASCII编码值是48,便是48
'0'是字符0,获取ASCII编码值
③0是数字0,本质也是0
比较一个int类型的数字是否等于0,或者给变量赋值。
④NULL是个表达式((void *)0),强制转换为void * 的0,本质也是0
用来比较指针是不是一个野指针
做者:Devil-wei