【问题标题】:what value does null really have?null 真正有什么价值?
【发布时间】:2009-08-14 16:34:17
【问题描述】:

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

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

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

谢谢大家:D

【问题讨论】:

标签: c# java language-agnostic null object


【解决方案1】:

答案分为两部分:

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

第二点是为什么要回答您的问题“但这不也是内存中的位置吗?”是“否” - 这只是一个规则,即零不被视为有效的内存位置。尝试访问它会导致异常。

编辑: According to Wikipedia(所以它必须是真的 8-)“一些架构使用带符号的地址空间并使用最大的负值”。所以它不一定在所有架构上都为零,但无论它在给定架构上具有什么值,该值都被认为是无效的内存位置。

【讨论】:

  • “这只是一个规则,零不被认为是有效的内存位置”
  • 该标准不要求零是无效地址,它要求每当您将地址与零进行比较时,编译器都必须将该零转换为该体系结构上的标准错误地址。有点巧合的是,在 x86 Linux 上,无效页面也为零,但并非必须如此。
【解决方案2】:

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

这很重要,因为这意味着正确创建新数组或对象只涉及擦除内存以为所有字段创建适当的默认值,然后在适当的情况下开始调用构造函数、变量初始化器等。

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

【讨论】:

  • 在 Ecma334 中,p122 它说:[注意:初始化为默认值通常是通过...将内存初始化为所有位为零...结束注释]。注意典型的限定符和 [Note ] 上下文。
  • @Henk:那是 C# - 我特意将自己限制在 .NET 而不是 C# :)
  • 乔恩,特定语言似乎不太可能以不同的方式实现这些。注释是关于“内存管理器”的。
  • @Henk:关键是 C# 的不同实现可以 以不同的方式实现这一点。例如,它可以被解释并使用“全 1”位模式。但是,同一 CLI 实现上的不同语言都需要使用相同的 null 表示。
【解决方案3】:

来自 C++ 背景,当谈到指针时,NULL 的标准定义是 0。我认为其他语言的工作方式类似。

【讨论】:

  • 这在大多数语言中都是正确的,只是在不同的 CPU/架构中确实有所不同。
  • 模糊地记得某些架构(PDP 变体?)有一个空指针,它不是为空,而是指向一个内存地址这对于取消引用同样无效。尽管谷歌搜索我找不到这个参考。
  • 不要混淆 C++ 代码中空指针的值,根据 C++ 标准的第 4.10/1 节,空指针的值必须为零,以及编译器使用的空指针的内部表示,任何方便的都可以。
【解决方案4】:

回答c#

CLR 有一个 null 操作码。

   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 的特殊值

【讨论】:

    【解决方案5】:

    并非所有语言都使用特定值,有时 null 是一个对象。动态语言通常有一个表示 null 的全局对象,当它们没有值时,对象引用被设置为该对象引用。在这些情况下,可以对 null 对象进行方法调用并创建相应的响应。

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

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

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

    【讨论】:

      【解决方案6】:

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

      根据Wikipedia,某些语言中的空指针可能是内存中的一个固定地址,用户程序可能无法访问,所以如果某个对象指向这个地址,则为空,否则不为空。

      【讨论】:

        【解决方案7】:

        RAM 的第一页通常受到用户空间程序的保护。这样,如果程序员忘记检查空指针,当程序尝试访问该位置时,程序至少会导致页面错误。

        所以虽然[0x00000000] 在技术上是一个真正的内存位置,但大多数程序无法访问它。

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

        【讨论】:

          【解决方案8】:

          http://googleit1st.com/search?hl=en&q=null+pointer

          空指针或空引用 Null 是一种特殊的指针值(或其他类型的对象引用),用于表示指针故意不指向(或引用)对象。这样的指针称为空指针。1许多实现使用值 0(所有位为零)来表示空指针,因为它位于大多数 CPU 的地址空间的底部(尽管有些架构使用带符号的地址空间并使用最负值)。当尝试访问此内存地址时,许多操作系统会生成异常。一些语言对这种指针使用其他命名法,例如,Pascal、Ruby 和 Lua 使用 nil2,Visual Basic 使用 Nothing,Python 使用 None。 Fortran 不认为 null 是一个常量,而是一个可以由 NULLIFY 指令设置并由 ASSOCIATED 函数测试的属性。 Taken from wikipedia

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-12-06
            • 1970-01-01
            • 1970-01-01
            • 2023-03-24
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多