【问题标题】:Difference between uninitialized and null pointer未初始化和空指针的区别
【发布时间】:2015-08-25 18:37:32
【问题描述】:

空指针和未初始化指针有什么区别吗? 这个问题是在一次采访中被问到的。 你能解释一下它们之间的区别吗?

【问题讨论】:

    标签: c pointers null


    【解决方案1】:

    嗯,区别就在于此。空指针被初始化为空,因此具有定义的含义。您可以检查它是否为空,并且取消引用它会(在我知道的所有平台上)导致程序因有意义的诊断而崩溃。您还可以在某些特定的技巧中使用空指针。 另一方面,未初始化的指针只是随机的,应该避免使用。

    【讨论】:

    • 那么,你不知道 DOS 了吗?或者任何嵌入式系统?因为它们不太可能因滥用空指针而立即崩溃。
    • 我的 DOS 经验非常有限。而且我对嵌入式系统没有任何经验。
    【解决方案2】:

    取一个未初始化的指针:

    int* ptr;//points to any location in memory
    

    取一个空指针:

    int* ptr = NULL;//normally points to 0x0 (0)
    

    如果取消引用,两者都会导致未定义的行为。 NULL 通常定义为 0

    【讨论】:

    • NULL 只是一个概念。它在 C 中由0 表示,但这并不一定意味着它指向地址 0x0。 stackoverflow.com/questions/7613175/…
    • 但这不是真的。 NULL 在语言中定义为 0,但在编译时,它可能指向硬件定义为 NULL 的其他位置。
    • 该语言只保证空指针,无论它可能由什么地址表示,都不同于任何有效指针。
    • @Joe 我确定 MSVC 中的NULL 定义为0(void*)0,但这仍然不意味着它在编译时实际上指向0x0 .
    • @NDeepK 不完全是。使用未初始化的指针是未定义的行为,但取消引用 NULL 指针也是未定义的行为(两者都可能导致崩溃)。不同之处在于未初始化的指针可以是任何值,但 NULL 指针具有确定的值(即NULL)。
    【解决方案3】:

    未初始化的指针存储未定义的值。

    空指针存储一个已定义的值,但该值由环境定义为不是任何成员或对象的有效地址。

    好的...我为您搜索了它,这是链接:Null pointer vs uninitialized pointer

    【讨论】:

    • @MSU_Bulldog 先生,我也google了一下,但无法理解空指针定义中提到的“由环境定义”的含义。是不是意味着一个变量的地址不能为0(null)?
    • 在大多数情况下,是的。除非你特别指定它为 NULL。
    • @NDeepK 表示保证空指针不同于其他任何指针。环境定义了它是什么。
    • @NDeepK 是对的。它可以分配为 0 或其他值,这取决于环境将指针定义为什么。因此,永远不要假设它是 0 或 NULL。
    【解决方案4】:

    基本区别在于,未启动的指针具有不确定的值,而 NULL 指针的已定义值是NULL

    关于 NULL 指针,来自C11,第 §6.3.2.3 章

    值为 0 的整型常量表达式或转换为 void * 类型的表达式称为空指针常量。如果将空指针常量转换为指针类型,则生成的指针(称为 空指针)保证比较不相等 指向任何对象或函数的指针。

    FWIW,宏 NULL<stddef.h> 中定义为空指针常量。

    【讨论】:

      【解决方案5】:

      接受回答后

      void foo(void) {
        void *uninitialized_pointer;
        void *null_pointer = null_pointer_generator();
        ...
      }
      

      uninitialized_pointer未初始化。它可能有一个有效的指针值。它可能有一个与NULL 比较的值。它可能没有 any 指针值。 C 甚至没有定义方法来复制或打印其值。

       // These are undefined behavior.
       void *another_pointer = uninitialized_pointer;
       unsigned x = uninitialized_pointer*0;
       printf("%p\n",  uninitialized_pointer);
      

      代码可以分配uninitialized_pointer,计算其大小或传递其地址。

       // These are defined behavior.
       uninitialized_pointer = malloc(1);
       uninitialized_pointer = NULL;
       printf("%zu\n", sizeof uninitialized_pointer);
       foo(&uninitialized_pointer);
      

      变量 null_pointer 的值与 空指针常量(见下文)相同,因此在 空指针 . 空指针 可能是唯一的位模式,或者系统中可能有许多位模式。它们全部空指针常量以及相互比较。 空指针可能是也可能不是系统中的有效地址,尽管它不会与程序中的任何对象、变量、成员、函数进行同等比较。

      尝试取消引用 空指针 是未定义的行为:它可能会导致段错误 - 也可能不会。


      NULL空指针常量。当分配给一个指针时,该指针是一个空指针。当0 分配给一个指针时,该指针是一个空指针。这些可能/可能不是不同的空指针。它们将相互比较。

        void *null_pointer1 = NULL;
        void *null_pointer2 = 0;
        // The 2 pointer may/may not have the same bit pattern.
        printf("%p\n%p\n", null_pointer1, null_pointer2);
      
        // They will always compare as equal.
        printf("%d\n", null_pointer1 == null_pointer2);
      
        // Always compare as unequal.
        int x;
        printf("%d\n", null_pointer1 == &x);
      

      【讨论】:

        【解决方案6】:

        是的。未初始化和空指针是有区别的。未初始化的指针可以指向任何(未知)内存位置。一个用NULL初始化的空指针;实现定义的空指针常量。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-28
          • 1970-01-01
          • 1970-01-01
          • 2015-07-21
          • 2021-01-26
          相关资源
          最近更新 更多