在C / C ++中,我们习惯在解除引用之前检查空指针,例如
int *p = malloc(sizeof(int));
if (p != 0)
{
/* Do something with the pointer */
}
因此,内存管理器永远不会返回指向第一个内存地址(p == 0
)的指针,因为调用程序将假定无法分配内存。
这是否意味着在整个系统内存空间和进程的内存空间中,第一个字节或字(用于对齐)始终未使用?或者是系统或内核使用的内存,它知道哪些空指针可以安全地取消引用?
答案 0 :(得分:4)
首先,为了清楚起见,malloc
返回0表示发出错误信号。
在大多数现代操作系统中,虚拟地址空间(程序中使用的地址)与物理地址空间(内存理解的实际地址)不同)。大多数现代操作系统使用分页。因此,程序中使用的地址(例如malloc
返回的地址)与物理地址不同。操作系统有一些机制可以在它们之间建立对应关系。
操作系统必须永远不会在物理地址0 处映射任何常规进程,并且如果进程尝试访问该地址,该地址将始终无效。为了自己的利益,操作系统本身可以根据需要访问地址0的内存。
答案 1 :(得分:2)
是的,有点儿。从技术上讲,你可以存储零地址,但Windows不允许 - 你得到访问冲突,Linux不允许 - 你得到分段错误。这样做有助于具有指定的特殊值,该特殊值意味着“空指针 - 明确指向任何活动对象的指针”。也许存在直接允许在地址零处存储数据的系统,但是仍然需要一些特殊值来表示“空指针”。
答案 2 :(得分:1)
在大多数系统中,物理地址0已经有了一些东西。一些旧的处理器只是在它们复位后才开始执行。其他人可能期望在那里有一个向量表(用于复位和中断的地址)。通常会将ROM映射到那里以包含处理器期望的这些特殊事物,因此在那里获得指针是没有意义的。
使用虚拟内存,您的应用及其所有分配都存在于映射到物理内存的虚拟内存空间中。我的猜测是程序映射到虚拟地址0,所以你仍然不会期望malloc返回0.这是我的一个猜测,因为我不是非常熟悉虚拟内存的细节布局。
顺便说一句,我经常认为处理器在从没有页面错误的NULL指针读取时应返回零。即使没有数据,这也可以允许推测预取数据。