使用空指针是不是意味着某些内存始终未被使用?

Posted

技术标签:

【中文标题】使用空指针是不是意味着某些内存始终未被使用?【英文标题】:Does the use of null pointers mean that some memory is always unused?使用空指针是否意味着某些内存始终未被使用? 【发布时间】:2011-09-08 14:06:56 【问题描述】:

在 C/C++ 中,我们习惯于在取消引用之前检查空指针,例如

int *p = malloc(sizeof(int));
if (p != 0)

    /* Do something with the pointer */

因此,内存管理器永远无法返回指向第一个内存地址(p == 0)的指针,因为调用程序将假定内存无法分配。

这是否意味着在整个系统内存空间和进程的内存空间中,第一个字节或字(用于对齐目的)始终未使用?还是系统或内核使用了这块内存,它知道可以安全地取消引用哪些空指针?

【问题讨论】:

【参考方案1】:

首先,明确一点,malloc 返回 0 意味着发出错误信号。

在大多数现代操作系统中,虚拟地址空间(程序中使用的地址)与物理地址空间(内存可以理解的真实地址)不同)。大多数现代操作系统都使用分页。所以程序中使用的地址(例如malloc返回的地址)与物理地址不同。操作系统有一些机制可以在它们之间建立对应关系。

操作系统绝不能简单地在物理地址 0 上映射任何内容对于常规进程,如果进程尝试访问该地址,该地址将始终无效。如果需要,操作系统本身可以访问地址 0 处的内存。

【讨论】:

返回的内存地址不是page-relative吗?也就是说,页面中的第一个位置不是由偏移量 0 寻址的 @Gnat 我不明白你的问题。 如果我有一个 32 字长的页面,其中第一个单词的索引相对于页面开头为 0,然后是 1, 2.. 31. 相对于页面本身的寻址显然是不是地址是如何分配的,而是一些操作系统指定的地址,我们真的不知道它是如何或为什么到达那里的。【参考方案2】:

是的,有点。从技术上讲,您可以将某些内容存储在地址零,但 Windows 不允许 - 您会遇到访问冲突而 Linux 不允许 - 您会遇到分段错误。这样做有助于获得一个指定的特殊值,这意味着“空指针 - 一个明显不指向任何活动对象的指针”。也许有些系统完全允许在地址 0 存储数据,但它们仍然需要一些特殊值作为“空指针”。

【讨论】:

是的,我知道,但这意味着地址 0 的内存永远无法分配,不是吗? @Gnat,据我所知那里有 IDT:en.wikipedia.org/wiki/Interrupt_descriptor_table @Gnat:至少没有堆分配。【参考方案3】:

在大多数系统中,物理地址 0 处已经存在某些内容。一些较旧的处理器在复位后直接从那里开始执行。其他人可能期望那里有一个向量表(复位和中断的地址)。通常一个 ROM 会被映射到那里以包含处理器期望的这些特殊内容,因此在那里获得指针是没有意义的。

使用虚拟内存,您的应用及其所有分配都位于映射到物理内存的虚拟内存空间中。我的猜测是程序被映射到虚拟地址 0,所以你永远不会期望 malloc 返回 0。这更像是我的猜测,因为我对虚拟内存的细节并不十分熟悉布局。

顺便说一句,我经常认为处理器在读取 NULL 指针时应该返回零,而不会出现页面错误。即使没有数据,这也允许推测性预取数据。

【讨论】:

这是有道理的,与上面针对 x86 的@Andrey 的链接有关。所以是的,地址 0 已被使用,但大多数人担心的不是任何事情。

以上是关于使用空指针是不是意味着某些内存始终未被使用?的主要内容,如果未能解决你的问题,请参考以下文章

void指针 (补充)

C++笔记--指针和引用

(转)空指针和野指针

Objective-C 空指针和野指针

Objective-C09-空指针和野指针

C++ 空指针和野指针