【问题标题】:If a pointer to pointer is NULL, then is it necessary that the pointer is also NULL?如果指向指针的指针为 NULL,那么指针是否也必须为 NULL?
【发布时间】:2023-03-28 02:27:01
【问题描述】:

假设我有一个结构

typedef struct point_t
{
  int x;
  int y;
}POINT;

我创建一个指向 POINT 的指针并将其初始化为 NULL。

POINT **ppPoint = NULL;

*ppPoint 也应该返回NULL 吗?

【问题讨论】:

  • 不能取消引用空指针,因此*ppPoint 无效。
  • 指向指针的指针遵循与所有其他指针相同的规则。
  • @Bathsheba,你能说明重新打开这篇文章的原因吗?我作为What EXACTLY is meant by “de-referencing a NULL pointer”? 的副本关闭——因为——无论是双指针、三指针还是四指针——指针都是指针。规则以同样的方式适用于他们。如果有人对 N-th 指针提出与上述相同的问题,您会重新提出问题吗?
  • @iammilind:这是一个链接问题,而不是重复问题。
  • 好吧,如果人们理解指针到指针不是一种特殊情况,那么它就是一种欺骗问题。但这里似乎并非如此。

标签: c pointers null


【解决方案1】:

这里有2层指针的事实实际上是无关紧要的。 NULL 中的外部指针意味着取消引用它是非法。因此,询问解除引用会获得什么价值是没有意义的。

考虑一下:

int *p = NULL; // modern practice would be to use nullptr anyway

if (0 == *p) // this is Undefined Behaviour!
{
    // do something, maybe?
}

您只是在其中添加了另一层,而不是int,而是point_t*,但这并没有什么区别。

Undefined Behaviour 的特点是任何事情都可能发生!您的程序可能会崩溃,或者它可能看起来可以工作,或者它有时可能会给您垃圾值,或者它可能...

【讨论】:

  • 吹毛求疵,评论应该是// Behavior undefined, this is!。
【解决方案2】:

空指针不指向任何东西。这适用于普通指针、函数指针和成员指针。它也适用于指向指针的指针。

因此,谈论“它指向什么”的价值是没有意义的。

【讨论】:

    【解决方案3】:

    您不能取消引用值为NULL 的指针。所以你将无法访问*ppPoint。

    您可以使用printf() 中的%p 格式化程序检查变量的地址以进行检查。

    printf("Address of ppPoint: %p", *ppPoint);
    printf("Address of *ppPoint: %p", *ppPoint);
    

    【讨论】:

      【解决方案4】:

      首先,对于神秘的 null 存在常见的误解。在这种情况下,有 3 个相关术语:

      • 空指针
      • 空指针常量
      • NULL 宏

      空指针常量是整数0 或转换为指针(void*)0 的整数。 NULL 宏保证是可移植的空指针常量。

      每当您将空指针常量(例如NULL)分配给任何指针时,该指针都会变为空指针。这允许编译器在内部将空指针表示为 0 以外的其他东西,因为地址 0x00...00 在许多系统上通常是有效的物理地址。

      具体来说,C17 6.3.2.3/3 对此进行了定义:

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


      当通过取消引用来访问空指针时,不会得到任何可预测的结果。根据 C17 6.5.3.2/4,这是未定义的行为:

      如果给指针分配了无效值,则一元 * 运算符的行为未定义。

      意味着任何事情都可能发生。如果幸运的话,您只会遇到系统崩溃。

      但是,您可以将空指针与另一个空指针或空指针常量进行比较,并且可以保证它们是相等的 (C17 6.5.9)。

      至于指针到指针是一种特殊情况,它不是。指向类型与上述任何规则都无关。总的来说,C 中的指针指向没有什么特别之处——它从来都不是特例,但总是被视为指针类型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-04-22
        • 2011-09-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多