空指针,野指针,nil,Nil,NULL,NSNULL

1. 空指针(百度)

问题一: 什么是空指针常量?
1.一个表示0值的整数常量,叫做空指针常量;
2.至于系统选取哪种形式作为空指针常量使用,则是实现相关的。
3.一般的 C 系统选择 (void*)0 或者 0 的居多(也有个别的选择 0L);

解释: 0、0L 、3 - 3以及 (void)0 等都是空指针常量(注意 (char) 0 不叫空指针常量,只是一个空指针值)。

问题二: 什么是空指针(null pointer)?
如果一个空指针常量 赋给了一个有类型的指针变量,那么这个指针就叫空指针。
1.空指针是一个特殊的指针,也是一个对任何类型都合法的指针值。
指针具有空指针值,表示当时他处于空置的状态,并且由系统保证空指针不指向任何实际的对象或者函数,   
 反过来说,任何对象或者函数的地址都不可能是空指针。
2.空指针用0表示,C语言保证这个值不会是任何对象的地址,给指针赋0则使他不在指向任何有意义的东西。
3.为了提高程序的可读性,标准库定义了一个和0等价的符号常量NULL,p=0/p=NULL,将p置为空指针值。

解释:如果 p 是一个指针变量,

若进行: p = 0;、p = 0L;、p = '\0';、p = 3 - 3;、p = 0 * 17; 中的任何一种赋值操作之后(对于 C 来说还可以是 p = (void*)0;)

问题三:空指针(null pointer)指向了内存的什么地方即空指针的内部实现?

标准并没有对空指针指向内存中的什么地方这一个问题作出规定,也就是说用哪个具体的地址值(0x0 地址还是某一特定地址)表示

空指针取决于系统的实现。

在实际编程中不需要了解在我们的系统上空指针到底是一个 zero null pointer 还是 nonzero null pointer,我们只需要了解一个指针是否是空指针就可以了——编译器会自动实现其中的转换,为我们屏蔽其中的实现细节。

不要把空指针的内部表示等同于整数 0 的对象表示——如上所述,有时它们是不同的。
问题四: 什么是 NULL?
 NULL 是一个标准规定的宏定义,用来表示空指针常量。
因此,除了上面的各种赋值方式之外,还可以用 p = NULL; 来使 p 成为一个空指针。

有些系统中这样来宏定义的

    #define NULL 0

char *p = NULL;

问题5: 在实际的操作中 如何判断某个指针是不是空指针?
可以通过与空指针常量或者其它的空指针的比较来实现
(注意与空指针的内部表示无关)。

指针变量p 是空指针的判断: (假设 p 是一个指针变量,q 是一个同类型的空指针,要检查 p 是否是一个空指针)

if ( p == 0 )

if ( p == 3 - 3 )

if ( p == NULL ) /* 使用 NULL 必须包含相应的标准库的头文件 */

2. 野指针

question?

操作不当造成的野指针,甚至会引起系统死机等比较严重的后果。 如果程序定义了一个指针,就必须要立即让它指向一个我们设定的空间或者把它设为NULL;

why?

如果没有这么做,那么这个指针里的内容是不可预知的,即不知道它指向内存中的哪个空间(即野指针),它有可能指向的是一个空白的内存区域,可能指向的是已经受保护的区域,甚至可能指向系统的关键内存,如果是那样就糟了,也许我们后面不小心对指针进行操作就有可能让系统出现紊乱,死机了。

原理?

NULL,如果是建立一个与指针相同类型的空间,实际上是在内存中的空白区域中开辟了这么一个受保护的内存空间,然后用指针来指向它,那么指针里的地址就是这个受保护空间的地址了,而不是不可预知的啦,然后我们就可以通过指针对这个空间进行相应的操作了;
如果我们把指针设为NULL,我们在头文件定义中的 #define NULL 0 可以知道,其实NULL就是表示0,那么我们让指针=NULL,实际上就是让指针=0,如此,指针里的地址(机器数)就被初始化为0了,而内存中地址为0 的内存空间……不用多说也能想象吧,这个地址是特定的,那么也就不是不可预知的在内存中乱指一气的野指针了。

注意?
  • free和delete只是把指针所指的内存给释放掉,但并没有把指针本身干掉。指针p被free以后其地址仍然不变(非NULL),只是该地址对应的内存是垃圾,p成了“野指针”。如果此时不把p设置为NULL,会让人误以为p是个合法的指针。
  • 用free或delete释放了内存之后,就应立即将指针设置为NULL,防止产生“野指针”。
  • 内存被释放了,并不表示指针会消亡或者成了NULL指针。(而且,指针消亡了,也并不表示它所指的内存会被自动释放。)
1、指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的默认值是随机的,它会乱指一气。 

2、指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针。 

3、指针操作超越了变量的作用范围。

3. nil,Nil,NSNULL,NULL

空指针,野指针,nil,Nil,NULL,NSNULL_第1张图片
屏幕快照 2018-01-04 14.52.41.png
nil,Nil,NULL只是区分不同类型的空指针
NSNULL代表是一个对象,这个对象代表0值

NSURL *url = nil;//对象指针为空
Class  class = Nil;//类指针为空
int *pointerInt = NULL;//基本数据类型为空

4.OC中返回空数据的处理

  • OC中nil是一个指向不存在的对象指针,
  • OC中的对象定义默认赋值为nil,而数组和字典里是不可以有nil的,但可以为[NSNull null];
  • OC在框架层面,Foundation定义了NSNull,即一个类方法+null,它返回一个单独的NSNull对象。
  • NSNull与nil以及NULL不同,因为它是一个实际的对象,而不是一个零值。
  • 当向nil发送消息时,返回NO,不会有异常,程序将继续执行下去;而向NSNull的对象发送消息时会收到异常。

5.OC中实际应用

// 判断字典对象的元素是否为空  
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:  
    @"iPhone", @"First", @"iPad", @"Second", nil];  
NSString *value = [dictionary objectForKey:@"First"];  
if ((NSNull *)value == [NSNull null]) {  
}  

// 判断数组元素是否为空  
NSString *element = [array objectAtIndex:2];  
if ((NSNull *)element == [NSNull null]) {  
}  
其他问题1: 可以定义自己的 NULL 的实现吗?

解释:NULL 是标准库中的一个符合上述条件的 reserved identifier (保留标识符)。所以,如果包含了相应的标准头文件而引入了 NULL 的话,则再在程序中重新定义 NULL 为不同的内容是非法的,其行为是未定义的

其他问题2:malloc 函数在分配内存失败时返回 0 还是 NULL?

解释: malloc 函数是标准 C 规定的库函数。在标准中明确规定了在其内存分配失败时返回的是一个 “null pointer”(空指针):

你可能感兴趣的:(空指针,野指针,nil,Nil,NULL,NSNULL)