我知道 NULL
(0x00000000) 是一个指向空的指针,因为操作系统不允许进程在此位置分配任何内存。但是,如果我使用 0x00000001(魔数(Magic Number)或代码指针),是否也可以安全地假设操作系统不允许在此处分配内存?
如果是这样,那么到哪里可以安全地假设?
最佳答案
标准(第一)
标准仅保证0
就指针而言是一个标记值。无法保证底层内存表示;它是实现定义的。
除了读取指针状态或写入新状态(包括解除引用或指针算术)之外,将指针设置为该标记值是未定义的行为。
虚拟内存
在虚拟内存时代(即每个进程都有自己的内存空间,独立于其他进程),空指针在进程内存空间中通常确实表示为 0。我实际上不知道任何其他架构,但我想在大型机中可能并非如此。
Unix
在 Unix 世界中,通常会为空值保留 0x8000 以下的所有地址空间。内存没有分配,实际上,它只是受到保护(即,置于特殊模式),因此如果您尝试读取或写入它,操作系统将触发段错误。
使用这样一个范围的想法是空指针不一定按原样使用。例如,如果您使用 std::pair<int, int>* p = 0;
为空,然后调用 p->second
, 然后编译器将执行指向 second
所需的算术运算(即 +4
一般)并尝试访问 0x4
处的内存直接地。数组显然使问题复杂化。
在实践中,这 0x8000
limit 应该足够实用以检测大多数问题(并避免内存损坏或其他问题)。在这种情况下,这意味着您可以避免未定义的行为 并获得“适当的”崩溃。但是,如果您使用的是大型阵列,则可能会超过它,因此它不是 Elixir 。
您的实现或编译器/运行时堆栈的特定限制可以通过文档或连续试验来确定。甚至可能有一种方法可以对其进行调整。
关于C++ - 安全指针范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12768659/