1

我有以下代码。

int *a = NULL;
int b;

b = *a;

它是否以任何方式未定义?我正在尝试访问 a 指向的位置,仅供阅读。它可以做什么错?

4

6 回答 6

5

它是否以任何方式未定义?

是的,行为未定义。

我正在尝试访问 a 指向的位置,仅供阅读。

指向的位置不存在。那里什么都没有。要读取某些内容,必须有一个要读取的值,但是空指针指向...无处。它没有指向任何东西。

于 2012-08-28T16:46:45.393 回答
3

实现专门选择空指针的物理值,以使它们“指向”在给定平台上不包含任何值的地址。这意味着那里没有什么可看的。此外,在现代虚拟内存平台上,甚至可能没有与该地址关联的特定“那里”。

如果您只是出于好奇而这样做,它仍然无法在典型的现代平台上运行:[虚拟] 内存区域通常是“不是您的”,这意味着硬件/操作系统保护机制将阻止您阅读它(通过使您的程序崩溃)。

同时,该语言指出,任何取消引用空指针的尝试都会导致未定义的行为,无论您取消引用它的目的是什么。

于 2012-08-28T16:53:01.977 回答
2

是的,这是完全未定义的行为。您正在取消引用一个空指针。什么事情都可能发生。

于 2012-08-28T16:46:41.943 回答
1

不要取消引用 NULL 指针。这就像穿越溪流,但更糟。我什至不确定你想要完成什么?您是否要初始化两个指向 NULL 的指针?

于 2012-08-28T16:53:15.043 回答
0

结果是不确定的,在不同的平台下会有所不同。

NULL 等于 0。因此说int* a = NULL意味着你创建了一个指向地址 0 的指针,它应该包含一个整数。

通过取消对 a 的引用,b = *a您可以指示程序转到地址 0 并获取数据。

现在,根据平台的不同,用户代码很可能无法访问地址 0。如果您没有在操作系统之上运行(例如在微控制器环境中),那么地址 0 通常是内部 ROM 的开头。在其他情况下,它可以是堆栈的开头等。

在大多数情况下,当您取消引用空指针时,您将获得空指针异常。

于 2012-08-28T19:48:12.073 回答
0

你有两个在这里弹出的警报。NULL标准严格禁止所有其他形式的空指针。不是因为它们通常在内部通过一个位模式来实现,0用于表示这样的指针,而是因为这是指针的一对一保留值,表明它没有指向任何地方。不要这样做。

有一个指向与整数值对应的地址的指针0是另一回事。您只能通过某种技巧来强制执行这样的值和对点的解释,例如

union over {
  int *a;
  uintptr_t b;
} ov;

ov.b = 0;
int c = *ov.a;

然后发生的事情完全取决于您的平台。如果0是您地址空间中的有效地址,这可能会起作用,但可能不会。除非你知道得更好,否则不要这样做。

于 2012-08-28T20:05:49.837 回答