`0x2` 是 C++ 中的空指针吗?

Is `0x2` a null pointer in C++?

在下面的代码中:

int* p = (int*)0x2;
*p = 1;

此代码导致分段错误。但是:

int* p = (int*)0x2;
cout << (p == nullptr);

输出为0。所以:

  1. 指向地址 0x2 的指针真的是空指针(这会导致分段错误)吗?
  2. 如何通过 if 语句处理像 0x2 这样的情况? (我的意思是,处理取消引用会导致分段错误的情况。因为正如您在 if (p == nullptr) 中看到的那样,这种情况没有得到处理)。
  3. 除了 0x2 之外,还有哪些地址取消引用指向它们的指针会导致分段错误,为什么?

您可能会在除 null 以外的其他地址上遇到分段错误。这只是意味着您正在尝试访问操作系统为您的程序保留的内存。例如,早期地址可能用于启动过程等。

另见 What is a segmentation fault?

唯一可转换为 std::nullptr 的整数值是 0。

0x2是否是一个有效的内存地址取决于你的程序。如果您只是将此内存位置别名为 int*,这是未定义的行为,您很幸运会遇到分段错误。

你 "handle" 像 0x2 这样的情况的方式是以某种方式构建你的程序,以保证 0x2 是一个有效的内存地址。仅地址通常是不够的。很难保证在大型代码库中没有悬挂指针,但通过智能地使用智能指针和引用,我们可以设计出相当安全的程序。通常你可以通过值传递来逃脱。

What are addresses other than 0x2 which dereferencing a pointer pointing to them causes a Segmentation Fault and why?

全部。这取决于您的程序(以及您的OS)。您不能只将随机内存位置解释为整数然后使用它们。除此之外,这肯定会违反 strict aliasing rule

Is a pointer pointing to address 0x2 really a null pointer (Which causes a Segmentation Fault)?

不,正如输出 0 所证明的那样,它不是空指针。

How can I handle cases like 0x2 by if statements? (I mean, handle cases in which dereferencing would cause a Segmentation Fault. Because as you see in if (p == nullptr) this case is not handled).

你不能。没有允许您的程序使用的所有地址的列表。

What are addresses other than 0x2 which dereferencing a pointer pointing to them causes a Segmentation Fault and why?

您的操作系统未分配给您的程序的所有地址。写入属于您的程序的某些地址也会导致未定义的行为,例如崩溃。

要么你知道像硬件这样的特殊地址,要么你分配内存并获得相应的地址。

Is a pointer pointing to address 0x2 really a null pointer

0x2 不是空指针常量。

null 的 value 未指定。理论上,它可能是 2。但在大多数系统上它是 0。您显示的输出表明 null 在您的系统上没有值 2。

(Which causes a Segmentation Fault)?

通过 null 进行间接访问并不是导致段错误的唯一原因。

How can I handle cases like 0x2 by if statements? (I mean, handle cases in which dereferencing would cause a Segmentation Fault.

您 "handle" 他们从不尝试通过无效指针进行间接访问。无法根据指针的值知道指针是否有效(除了,我们知道 null 永远不会有效)。

What are addresses other than 0x2 which dereferencing a pointer pointing to them causes a Segmentation Fault and why?

从 C++ 的角度来看:在其生命周期之外访问任何对象会导致程序的行为未定义。如果地址 X 处没有对象,则访问 *X 是未定义的行为,除非另有说明。对象是通过定义变量并使用 new-expressions.

创建的

从 OS 的角度来看,这些事情会导致段错误:所有地址都没有映射到任何内存。所有写入只读内存。