什么是NULL背后?

时间:2016-03-28 14:42:11

标签: c memory null

在许多C实现中(但不是all),NULL对应于进程的逻辑地址0.当我们尝试取消引用NULL时,我们会得到一个分段错误,因为{{1 “映射”到既不可读也不可写的内存段。

是否存在具有与虚拟NULL地址对应的真实物理地址的系统?如果是这样,那里可能会存储什么?或者NULL纯粹是一个没有物理对应物的虚拟地址?

5 个答案:

答案 0 :(得分:1)

NULL实现定义

这是一个宏,它扩展为实现定义的空指针常量

"it depends" @I3x

  

是否存在与虚拟NULL地址对应的真实物理地址?

在某些平台上:是的,在其他平台上:不。它是实现定义。

  

如果是这样,那里可能会存储什么?

在某些平台上:一个值,可能为0.此值可能/可能无法访问。在其他人:简单的无法访问。它是实现定义。

  

NULL纯粹是一个没有物理对应物的虚拟地址?

在某些平台上:它是一个没有对应的虚拟地址。在其他人可能是一个真实的地址。它是实现定义。

答案 1 :(得分:1)

来自C标准论文 ISO / IEC 9899:201x (C11)§6.3.2.3指针

  
      
  1. 值为0的整数常量表达式,或者这样的   表达式转换为类型void *,称为空指针   不变。如果将空指针常量转换为指针   类型,保证结果指针,称为空指针   比较不等于指向任何对象或函数的指针
  2.   

这意味着如果与0值比较,NULL指针应该给出结果为TRUE,并且如果转换为算术类型,它将解析为值= 0。 但它也意味着编译器必须为空指针生​​成一个值,该空指针保证不是代码运行环境中存在的地址(比较相等)(这应该更标准化)。 /> 范围是使代码可移植,使得NULL指针上的每个操作必须在任何CPU或体系结构上给出相同的结果

注意:在实际方面保证NULL指针不等于运行环境中的任何地址有两种方法。第一个将适用于存在无效地址的平台,从而利用这些无效地址。第二种是通常保留范围的地址,通常为0.后者意味着平台,OS主要是注意使该地址无效,因为它不可用然后可以永远不会等于任何其他指针,否则总会有一个对象可以合法地使用该地址,从而使其与NULL指针的地址比较有效。这一点很重要,因为缺少任何基础设施,就像操作系统一样,它会处理无效值,我们可能会遇到冲突的情况。一个例子是当使用C编译器进行基本编程,操作系统和内核时,如果处理器使用地址0的内存来保存中断服务地址,则指向该对象的指针的值为0.在这种情况下,编译器应该使用不同的NULL指针的值,但是如果OS可以访问整个寻址空间。为了允许完整的内存管理,没有适用于NULL指针的值 在用户或内核HL代码上,这不是问题,因为总有一些地址通常是不允许的,然后可以用作NULL指针值。

答案 2 :(得分:0)

当然在某些计算机上,地址为0的实际内存。在其他计算机上,可能没有。甚至有一些硬件设计的答案可能取决于内存映射芯片或芯片组的临时状态。

但在所有情况下,取消引用NULL指针都是未定义的行为。

答案 3 :(得分:0)

是的,大多数(所有?)系统的实际物理地址为零,它只能从虚拟地址空间后面的进程无法访问,该虚拟地址空间将虚拟地址重新映射到(不同的)物理地址。在这些过程中,地址零只是保留为未映射到任何地方,就像其余大部分地址空间一样。

然而,事实上,所有基于x86的处理器直到今天才开始进入“实模式”。这是8086兼容模式。在这种处理器模式下,不仅存在物理可寻址地址为零,而且该地址实际上是中断向量表所在的位置,这是处理器在处理中断时从中读取的位置。

答案 4 :(得分:-1)

  

在许多C实现中(但不是全部),NULL对应于进程的逻辑地址0。

不,这是看错的方法。根据定义,空指针不对应于除自身之外的任何内容,并且在任何意义上,C都不会将空指针绑定到任何特定地址。

充其量,你可以说一些实现'空指针的表示具有指向驻留在机器地址0的对象的指针的表示的形式。由于空指针与对象或函数的每个指针的比较不相等,因此,这种情况要求C程序可以引用的任何对象或函数都不可能驻留在该地址。

  

当我们尝试取消引用NULL时,我们会得到分段错误

这是调用未定义行为时可能出现的大量观察行为之一。根据经验,当以您描述的特定方式调用未定义的行为时,它更可能被观察到。它绝不是由C保证的,实际上,广泛使用的实现在经验上表现出不同的行为。

  

因为NULL"映射"到一个既不可读也不可写的内存段。

但是,您正在深入研究实施细节。

  

是否存在与虚拟NULL地址对应的真实物理地址?

不,因为空指针不是地址。它是一个指针值,对取消引用显然无效。从技术上讲,虽然C将某些指针值称为"地址",但它既不需要也不依赖于任何指针值作为机器地址,既不是物理地址也不是虚拟地址。然而,即使在C的术语意义上,空指针的值也不是地址。 &运算符从不生成此值,并且取消引用无效 - 它显式无法与任何对象或函数对应。

  

如果是这样,那里可能会存储什么?或者NULL纯粹是一个没有物理对应物的虚拟地址?

尽管空指针值确实以指向驻留在机器地址0的对象/函数的指针的方式表示,但这是无关紧要的,因为在这种情况下C程序可以永远不会访问居住在该地址的任何内容。因此,就该计划而言,那里没有任何东西。就硬件和操作系统内核而言,另一方面,外部程序'记忆的观点在很大程度上是不相关的如果一个人坚持考虑内核对存储在物理内存中的内容的视图,该视图来自外部程序的空指针表示,那么它在很大程度上取决于系统。