我有以下代码。
int *a = NULL;
int b;
b = *a;
它是否以任何方式未定义?我正在尝试访问 a 指向的位置,仅供阅读。它可以做什么错?
它是否以任何方式未定义?
是的,行为未定义。
我正在尝试访问 a 指向的位置,仅供阅读。
指向的位置不存在。那里什么都没有。要读取某些内容,必须有一个要读取的值,但是空指针指向...无处。它没有指向任何东西。
实现专门选择空指针的物理值,以使它们“指向”在给定平台上不包含任何值的地址。这意味着那里没有什么可看的。此外,在现代虚拟内存平台上,甚至可能没有与该地址关联的特定“那里”。
如果您只是出于好奇而这样做,它仍然无法在典型的现代平台上运行:[虚拟] 内存区域通常是“不是您的”,这意味着硬件/操作系统保护机制将阻止您阅读它(通过使您的程序崩溃)。
同时,该语言指出,任何取消引用空指针的尝试都会导致未定义的行为,无论您取消引用它的目的是什么。
是的,这是完全未定义的行为。您正在取消引用一个空指针。什么事情都可能发生。
不要取消引用 NULL 指针。这就像穿越溪流,但更糟。我什至不确定你想要完成什么?您是否要初始化两个指向 NULL 的指针?
结果是不确定的,在不同的平台下会有所不同。
NULL 等于 0。因此说int* a = NULL
意味着你创建了一个指向地址 0 的指针,它应该包含一个整数。
通过取消对 a 的引用,b = *a
您可以指示程序转到地址 0 并获取数据。
现在,根据平台的不同,用户代码很可能无法访问地址 0。如果您没有在操作系统之上运行(例如在微控制器环境中),那么地址 0 通常是内部 ROM 的开头。在其他情况下,它可以是堆栈的开头等。
在大多数情况下,当您取消引用空指针时,您将获得空指针异常。
你有两个在这里弹出的警报。NULL
标准严格禁止所有其他形式的空指针。不是因为它们通常在内部通过一个位模式来实现,0
用于表示这样的指针,而是因为这是指针的一对一保留值,表明它没有指向任何地方。不要这样做。
有一个指向与整数值对应的地址的指针0
是另一回事。您只能通过某种技巧来强制执行这样的值和对点的解释,例如
union over {
int *a;
uintptr_t b;
} ov;
ov.b = 0;
int c = *ov.a;
然后发生的事情完全取决于您的平台。如果0
是您地址空间中的有效地址,这可能会起作用,但可能不会。除非你知道得更好,否则不要这样做。