C++ 内存中是否有地址为NULL(0)的物理部分?

C++ 内存中是否有地址为NULL(0)的物理部分?,c++,memory,pointers,null,C++,Memory,Pointers,Null,我知道有一句老话,当你想指出这个特定的指针不指向任何东西时,它应该被设置为NULL(实际上是0),但我想知道的是,内存的物理部分地址不是NULL(0)?除非你写一个系统内核,否则从你的角度来看,没有这样的内存位置。您的地址位于虚拟地址空间中,这意味着它们不是物理地址。CPU通过查找系统表将它们转换为物理地址。物理地址始终为0(但不一定映射到物理RAM),但在典型平台上,任何访问通常都将在虚拟地址空间中执行(正如jweyrich在下面指出的,您可以使用mmap等直接映射物理地址空间),因此任何对地

我知道有一句老话,当你想指出这个特定的指针不指向任何东西时,它应该被设置为NULL(实际上是0),但我想知道的是,内存的物理部分地址不是NULL(0)?

除非你写一个系统内核,否则从你的角度来看,没有这样的内存位置。您的地址位于虚拟地址空间中,这意味着它们不是物理地址。CPU通过查找系统表将它们转换为物理地址。

物理地址始终为0(但不一定映射到物理RAM),但在典型平台上,任何访问通常都将在虚拟地址空间中执行(正如jweyrich在下面指出的,您可以使用
mmap
等直接映射物理地址空间),因此任何对地址0的读/写尝试都会引发某种异常

在更简单的处理器(比如微控制器等)上,可能没有这样的保护,所以如果您试图写入地址0,就不会有任何问题

还要注意的是,空指针不一定要指向地址0;唯一的保证是它将比较等于整数值
0

是的,在许多系统(尤其是嵌入式系统)中,有一个内存地址0,可以合法地从中读写


在这样的系统上,设置陷阱捕捉这样的读/写可能是可选的。

是的,计算机可以有一个物理地址0。例如,在旧的DOS时代,你经常会在那里戳来戳去——这就是中断表开始的地方——因此,如果你想知道按键或定时器中断会运行什么,那么你可以创建一个指向指针数组的指针,指向0。我在几年前回顾了C++标准中的措辞,以查看这是否是一个系统上的未定义行为,其中地址0应该是可访问的(在CPU /体系结构级别)。,我的记忆是,它没有明确地说这会导致未定义的行为。不过,它基本上保留在将0放入指针时加载非0值的权利,将指针与0进行比较等:0是一个特殊的哨兵值,它可以做任何它喜欢的事,所以如果你想“按书”去做的话然后你就必须四处走动。

在内核空间中,yes NULL可以是一个有效的地址。在用户空间中,no。至于物理地址,yes总是有地址零,但程序使用的是逻辑地址。

请注意,即使值0比较等于C/C++NULL指针,在标准中也不能保证NULL指针实际上,在进程的(虚拟)地址空间中引用地址零(通常是这样,但你知道,一定会有一些微控制器在那里等),因此
*(reinterpret_cast(&my_pointer))
可能不会
==0


在某些Unix版本上(但不在Linux上)每个进程都有一个只读页面,它只包含零字节,在地址空间中映射到它的地址空间。在这些机器上,空指针总是指向零值。在那里有软件利用这个特性,当移植到Linux或Windows时崩溃。

,因为这是加标签的C++,应该注意到标准。保证通过取消引用尝试访问“空指针”会引发未定义的行为:

1.9程序执行[简介执行] 还描述了某些其他操作 在本国际标准中: 未定义(例如 取消对空指针的引用)。 [注:本国际标准 不要求 包含 未定义的行为。]

…失败的
动态\u cast
的效果是空指针,删除空指针没有效果,最后,“空指针常量”是==整数表达式
0

4.10指针转换[conv.ptr]
  • 空指针常量是整型常量表达式(5.19) 计算结果为零的整数类型的右值

  • 总是有一个0的物理地址
    -可能某个地方有一个奇怪的微控制器,由于某种原因没有定义0的物理地址。@Oli Charlesworth:
    但是在一个典型的平台上,任何访问都将在虚拟地址空间中执行
    -这不完全正确。例如,Linux允许您
    mmap()
    /proc/sys/vm/mmap\u min\u addr
    设置为0时,地址0。这就是利用空指针解引用错误的原因:-)@Skizz:一些微控制器确实将某些物理地址映射到RAM以外的位置,例如I/O寄存器等。,因此,我将相应地更新答案。Skizz:是的-许多CPU:s从地址0及以上映射SDRAM。如果没有附加SDRAM,地址0就不被定义。@ OLI CARSLISVESY,指针甚至可以指向某个CPU登记器,对吗?请看我关于C++的代码> MMAP < /C>的注释。@ JWYRICH MMAP不是C或C++标准的一部分,它是POSIX API的一部分。@莱特梅耶贝:当然,但是C和C++标准没有定义系统应该如何映射它的内存。或者是吗?@jweyrich不,但它们定义了您使用的是逻辑内存空间,而不是物理内存空间。@Let_Me_Be:是吗?即使它们这样做了,它们大概也不会指定逻辑地址空间和物理地址空间之间的映射?所以它可以是直接的。所以你们告诉我们,我们使用的指针的内容不一定是物理地址,它取决于平台?首先,它通常不是物理地址,而是虚拟地址。其次,一切都取决于平台。我自己从未见过这种情况,但我只是在另一个回答中说了与Oli Charlesworth相同的话:“还要注意,空指针不一定要指向地址0;唯一的保证是它将与整数值0进行比较”。@ybungalobill_a