这可能是一个非常基本的问题。我知道有一个 C 约定将空指针的值设置为零。您是否有可能在 Windows 中为新变量分配空间,而该分配空间的地址恰好为零?如果不是,通常是什么占据该地址区域?
5 回答
在 MS-DOS 上,空指针是一个相当有效的指针,并且由于操作系统在实模式下运行,实际上有可能用垃圾覆盖 0x0 地址并破坏内核。您可以执行以下操作:
int i;
unsigned char* ptr = (unsigned char *)0x0;
for(i = 0; i < 1024; i++)
ptr[i] = 0x0;
现代操作系统(例如 Linux、Windows)在保护模式下运行,从不让您直接访问物理内存。
处理器会将物理地址映射到您的程序将使用的虚拟地址。
它还跟踪您访问的内容,如果您敢触摸不属于您的东西,您会遇到麻烦(您的程序会出现段错误)。这绝对包括尝试取消引用 0x0 地址。
当您“将指针的值设置为零”时,如
int *p = 0;
正如您似乎相信的那样,它不一定最终指向物理地址零。当指针被分配一个常量零值(或用它初始化)时,编译器需要识别这种情况并以特殊方式处理它。编译器需要用依赖于实现的空指针值替换那个零。后者不一定指向零地址。
空指针值应该由不会用于任何其他目的的物理地址表示。如果在某些实现中物理地址零是可用地址,那么这种实现将不得不使用不同的物理地址来表示空指针。例如,某些实现可能会0xFFFFFFFF
为此目的使用地址。在这样的实现中,初始化
int *p = 0;
实际上将p
使用物理初始化0xFFFFFFFF
,而不是使用物理零。
PS 您可能想看看常见问题解答:http ://c-faq.com/null/index.html ,它主要专门针对该问题。
该值0
没有特殊含义。将指针设置为 0 是惯例,C 编译器必须相应地解释它。但是,与物理地址 0 没有任何联系,事实上,该地址可以是有效地址。在许多系统中,虽然较低的地址包含与硬件相关的地址,例如中断向量或其他。例如,在 Amiga 上,地址 4 是操作系统的入口点,这也是一个任意决定。
如果分配空间的地址为零,则可用内存不足。这意味着您的变量无法分配。
0x0 处的地址是 CPU 上电时开始执行的位置。通常在这个地址有一个跳转到 BIOS 代码和 IIRC 前 64K(或更多)保留用于其他任务(由 BIOS/UEFI 确定)。这是一个应用程序无法访问的区域。
鉴于应该清楚在 Windows 中的地址 0x0 处不能有变量。