在“计算机系统:程序员的角度”,第2.1节(第31页)中,它说:
C中指针的值是某个存储块的第一个字节的虚拟地址。
对我而言,听起来C指针的值可以取0到[虚拟内存大小 - 1]的值。是这样的吗?如果是,我想知道是否有任何机制可以检查程序中的所有指针是否都分配了合法值 - 值至少为0且最多为[虚拟内存的大小 - 1],以及内置此类机制的位置 - 在编译器? OS?或其他地方?
答案 0 :(得分:2)
C中的指针是一个抽象对象。 C标准提供的唯一保证是指针可以指向C中所需的所有内容:函数,对象,超出对象末尾的一个,以及NULL。
在典型的C实现中,指针可以指向虚拟内存中的任何地址,而某些C实现在很大程度上故意支持这一点。但是,有并发症。例如,用于NULL的值可能难以用作地址,并且将针对一种类型创建的指针转换为另一种类型可能会失败(由于对齐问题)。此外,存在合法的非典型C实现,其中指针不以正常方式直接与内存地址相关联。
如果不了解C标准的规则以及您使用的C实现的规则,您不应该期望使用指针来任意访问内存。
C中没有机制可以检查程序中的指针是否有效。程序员负责正确使用它们。
答案 1 :(得分:2)
没有进程可以检查指针的有效性,因为无效指针的使用还有未定义的效果。
通常指针不可能保持在可寻址范围之外的值,因为两者将具有相同的可用范围 - 例如两者都是32位。但是,某些CPU具有关于指针对齐的规则,这些规则可能会使某些地址对某些类型的数据无效。一些运行时,例如64位Objective-C,它是C的严格超集,使用错误对齐的指针将文字对象伪装成堆上的对象。
在某些情况下,完整的地址空间由指令集定义为一件事,但由特定的硬件实现为另一个。历史上的一个例子是原始的68000,它定义了一个32位的空间,但只有24个地址线。非常早期的Mac OS版本使用备用的8位来描述数据块的标志,依靠硬件来忽略它们。
所以:
在实践中,如果您的地址对于该硬件而言是非法的,那么通常会发生这种情况,但是如果合法是处理器例外,则会被访问。
答案 2 :(得分:0)
出于实际目的,C指针是NULL或其他内存地址。我从来没有听说过NULL在现实生活中只有零。如果它是一个内存地址,你不应该“关心”实际数字是多少;只是传递它,取消引用它等。