c指针可以取值的范围

range of values a c pointer can take?

本文关键字:范围 指针      更新时间:2023-10-16

在"计算机系统:程序员的视角"第2.1节(第31页)中,它说:

C中指针的值是某个存储块的第一个字节的虚拟地址。

对我来说,听起来C指针的值可以取从0到[虚拟内存大小-1]的值。是这样吗?如果是,我想知道是否有任何机制可以检查程序中的所有指针是否都分配了合法值——值至少为0,最大为[虚拟内存大小-1],以及这种机制在编译器中的内置位置?OS?还是其他地方?

没有任何进程检查指针的有效性,因为使用无效指针无论如何都会产生未定义的效果。

通常,指针不可能保持可寻址范围之外的值,因为两者具有相同的可用范围——例如,两者都是32位。然而,一些CPU有关于指针对齐的规则,这可能会使某些地址对某些类型的数据无效。一些运行时,例如64位Objective-C,它是C的严格超集,使用不正确对齐的指针将文字对象伪装成堆上的对象。

还有一些情况下,完整的地址空间由指令集定义为一回事,但由特定硬件实现为另一回事。历史上的一个例子是最初的68000,它定义了一个32位空间,但只有24条地址线。早期版本的Mac OS使用备用的8位作为描述数据块的标志,依靠硬件来忽略它们。

因此:

  • 没有运行时有效性检查
  • 即使存在,有效性的含义通常取决于CPU的特定型号(而不仅仅是系列)或操作系统的特定版本(同上),从而使检查成为一项比你想象的不那么琐碎的任务

在实践中,如果您的地址在硬件上是非法的,但被合法访问,通常会发生什么,这是处理器的例外。

C中的指针是一个抽象对象。C标准提供的唯一保证是指针可以指向C中所有需要的东西:函数、对象、对象末尾的一个和NULL。

在典型的C实现中,指针可以指向虚拟内存中的任何地址,一些C实现在很大程度上有意支持这一点。然而,也存在一些复杂情况。例如,用于NULL的值可能很难用作地址,并且将为一种类型创建的指针转换为另一种类型可能会失败(由于对齐问题)。此外,还有一些合法的非典型C实现,其中指针不能以正常方式与内存地址直接相关。

在不了解C标准和您使用的C实现的规则的情况下,您不应该期望任意使用指针来访问内存。

C中没有任何机制可以检查程序中的指针是否有效。程序员有责任正确使用它们。

出于实际目的,C指针要么是NULL,要么是指向其他对象的内存地址。在现实生活中,我从来没有听说过NULL是零。如果这是一个内存地址,你不应该"关心"实际数字是多少;只是把它传来传去,取消引用等等。