未初始化指针和空指针的区别。

7

空指针和未初始化指针有什么区别吗?这个问题在面试中被问到。请解释一下它们之间的不同。

6个回答

7

那么,它们的区别就在于此。空指针被初始化为null,并且具有定义的含义。您可以检查它是否为空,并对其进行取消引用将(我所知道的所有平台上)导致程序崩溃并显示有意义的诊断信息。您也可以在某些特定的黑客中使用空指针。 另一方面,未初始化的指针只是随机值,应该避免使用。


1
那么,你不再了解DOS了吗?或者任何嵌入式系统?因为这些系统不太可能在误用空指针时立即崩溃。 - Deduplicator
3
我对DOS的经验极其有限,并且没有嵌入式系统的经验。 - SergeyA

4

拿一个未初始化的指针:

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

拿一个空指针:

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

如果对其进行解引用,两者都会导致未定义的行为。 NULL 通常被定义为 0


6
"NULL"只是一个概念,它在C语言中用"0"表示,但这并不一定意味着它指向地址"0x0"。https://dev59.com/gFvUa4cB1Zd3GeqPw8zI - PC Luddite
2
但这并不是真的。在语言中,NULL被定义为0,但在编译时,它可能指向硬件定义为NULL的其他位置。 - PC Luddite
3
该语言仅保证空指针,无论其代表的地址是什么,都与任何有效指针不同。 - Deduplicator
1
@Joe 我确定在MSVC中,NULL被定义为0(void*)0,但这并不意味着在编译时它实际上指向0x0 - PC Luddite
4
不完全正确。使用未初始化的指针是未定义行为,但是解引用空指针也是未定义行为(两者都可能导致崩溃)。区别在于,未初始化的指针可以是任何值,而空指针有一个确定的值(即“NULL”)。 - PC Luddite
显示剩余6条评论

3

接受答案后

void foo(void) {
  void *uninitialized_pointer;
  void *null_pointer = null_pointer_generator();
  ...
}
< p > 未初始化指针未初始化状态下。它可能具有有效的指针值。它可能具有与NULL相比较的值。它可能没有任何指针值。 C语言没有定义方法甚至复制或打印其值。

 // These are undefined behavior.
 void *another_pointer = uninitialized_pointer;
 unsigned x = uninitialized_pointer*0;
 printf("%p\n",  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);

3

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

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

好的...我为您谷歌了一下,这里是链接:Null pointer vs uninitialized pointer


@MSU_Bulldog 先生,即使我谷歌了一下,也无法理解“由环境定义”这个术语在空指针的定义中的含义。这是否意味着一个变量不能有一个地址为0(null)的情况? - Namandeep_Kaur
大多数情况下是这样的。除非您明确将其分配为NULL。 - MSU_Bulldog
@NDeepK 的意思是,空指针保证与任何其他指针不同。环境定义了它的含义。 - PC Luddite
@NDeepK说得没错。指针可以被赋值为0或其他任何值,这取决于环境如何定义它。因此,不要假设它会是0或NULL。 - MSU_Bulldog

3
区别在于未初始化的指针具有不确定的值,而空指针具有一个NULL定义值。
关于空指针,在C11中,第§6.3.2.3章节如下所述:

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

顺便提一下,宏NULL<stddef.h>中被定义为一个空指针常量。

2

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接