C# null真正有什么值?

C# null真正有什么值?,c#,java,language-agnostic,null,object,C#,Java,Language Agnostic,Null,Object,(我知道null是什么,它的用途是什么) 问:好吧,假设我们用任何语言引用一个对象。计算机在内存中为该引用留出一点32位(或其他大小,取决于计算机的设计)空间。可以将该内存分配给表示对象在内存中位置的值。但是,当我将引用设置为null时,它实际上有什么值?(参考设置中的各个位是什么)这些位刚刚调零了吗?但那不也是记忆中的一个位置吗?计算机如何判断引用包含null而不是对对象的引用 我知道这不是一个“重要”的问题,但我很好奇它是如何工作的 谢谢各位:D<P/> > P >来自C++背景的指针的空定

(我知道null是什么,它的用途是什么)

问:好吧,假设我们用任何语言引用一个对象。计算机在内存中为该引用留出一点32位(或其他大小,取决于计算机的设计)空间。可以将该内存分配给表示对象在内存中位置的值。但是,当我将引用设置为null时,它实际上有什么值?(参考设置中的各个位是什么)这些位刚刚调零了吗?但那不也是记忆中的一个位置吗?计算机如何判断引用包含null而不是对对象的引用

我知道这不是一个“重要”的问题,但我很好奇它是如何工作的


谢谢各位:D<P/> > P >来自C++背景的指针的空定义是0。我假设其他语言的工作方式也类似。

在.NET中,空值由“全零”位模式表示

这一点很重要,因为这意味着正确创建新数组或对象只需要在开始调用构造函数、变量初始值设定项等之前擦除内存,为所有字段创建适当的默认值


(我一直在试图找到这一点的具体位置,但到目前为止我失败了……但这是唯一有意义的实现。我会继续寻找。)

答案有两个方面:

  • 该值为零(即该值中的所有位均为零)
  • 零永远不会被视为有效地址

第二点是为什么你的问题“但那不也是内存中的一个位置吗?”的答案是“不”-这只是一条规则,零不被认为是有效的内存位置。试图访问它将导致异常

编辑:(因此它必须是真的8-“某些体系结构使用有符号的地址空间并使用最负的值”。所以它不一定在所有的架构上都是零,但是不管它在给定架构上有什么值,这个值都被认为是无效的内存位置

计算机如何判断引用包含null而不是对对象的引用

根据,某些语言中的空指针可能是内存中的固定地址,用户程序可能无法访问该地址,因此,如果某些对象指向该地址,则为空,否则为空。

空指针或空引用
Null是一个特殊的指针值(或其他类型的对象引用),用于表示指针有意不指向(或引用)对象。这样的指针称为空指针。许多实现使用0值(所有位为零)来表示空指针,因为它位于大多数CPU地址空间的底部(尽管有些体系结构使用有符号地址空间并使用最负的值)。当尝试访问此内存地址时,许多操作系统都会生成异常。有些语言对这种指针使用其他术语,例如Pascal、Ruby和Lua使用nil,Visual Basic不使用任何东西,Python不使用任何东西。FORTRAN不认为NULL是常量,而是可以由NulLIFY指令设置并由相关函数测试的属性。p> 并非所有语言都使用特定的值,有时null是一个对象。动态语言通常有一个全局对象,它表示null,当对象引用没有值时,会将其设置为null。在这些情况下,可以对null对象进行方法调用,并创建相应的响应

例如,在Ruby中有一个名为nil的单例和常见方法,如or、nil?和to_都有适当的默认实现,如果在null对象上调用它们,您会期望这些实现

在Java中,null在虚拟机规范中被彻底指定。它的实际值并没有真正指定,而是当字节码指令看到它时应该发生什么

Null通常通过将对象引用设置为指向nil对象来“处理”。但是抽象程度较低的语言可以使用零作为值,零是内存中的一个位置,但是操作系统会停止程序的实际编写,而不是内核转储或以其他方式停止程序#

CLR有一个空操作码

   String s = "ff";

   s = null;
生成此IL

  .locals init ([0] string s)
  IL_0000:  nop
  IL_0001:  ldstr      "ff"
  IL_0006:  stloc.0
  IL_0007:  ldnull
  IL_0008:  stloc.0

如您所见,有一个ldnull操作码,用于处理null的特殊值。RAM的第一页通常受到用户空间程序的保护。这样,如果程序员忘记检查空指针,当程序试图访问该位置时,程序至少会导致页面错误

因此,虽然从技术上讲,
[0x00000000]
是一个真实的内存位置,但大多数程序无法访问它


x86
如果我没记错的话,处理器在那里有一个特殊的表。

请看(但我不喜欢在答案中引用Wikipedia)。这在大多数语言中都是正确的,并且只在CPU/体系结构中有所不同。我模糊地记得,某些体系结构(PDP变体?)的空指针不是空的,但指向了一个对解引用同样无效的内存地址。尽管Google不能找到这个引用,但是不要混淆C++代码中空指针的值,它必须是C++标准的每部分4.10/1,以及编译器使用的空指针的内部表示,这可以是任何方便的。“这只是一个规则,认为零是无效的内存位置”。该标准并不要求零是无效地址,它要求每当您将地址与零进行比较时,编译器必须将该零转换为该体系结构上的标准错误地址。有点巧合的是,在x86 Linux上,无效页也为零,但不一定为零。在Ecma334,p122中,它说:[注意:初始化为默认值通常是通过将内存初始化为