我可能错了,但我似乎记得对于给定的内存分配,例如
char *p = malloc(4);
指针p
是分配和中所有字节的有效指针,用于超出该分配的第一个字节。
因此,要通过指针p
访问内存,只有偏移p[0] .. p[3]
才有效。但是对于指针比较&( p[4] )
也是一个有效的指针。
答案 0 :(得分:4)
&p[4]
或p + 4
是一个有效的指针,但不能解除它。
C11 6.5.6加法运算符
[...]如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出;否则,行为未定义。 如果结果指向数组对象的最后一个元素之后,则不应将其用作评估的一元
*
运算符的操作数。
答案 1 :(得分:2)
此答案假设p
是char *
。
但是对于指针比较&(p [4])也是有效的。
当p + 4
位于{0,1,2,3,4} {{1}时,指针&( p[4] )
(或p + N
有效与N
进行比较},<
或<=
。这在C11 6.5.8:5中有说明:
当比较两个指针时,结果取决于指向的对象的地址空间中的相对位置。如果两个指向对象类型的指针都指向同一个对象,或者两个指针都指向同一个数组对象的最后一个元素,则它们相等。如果指向的对象是同一聚合对象的成员,则指向稍后声明的结构成员的指针比指向结构中先前声明的成员的指针大,指向具有较大下标值的数组元素的指针比指向同一数组的元素的指针大。下标较低 值。指向同一个union对象的成员的所有指针都比较相等。如果表达式P指向数组对象的元素,并且表达式Q指向同一数组对象的最后一个元素,则指针表达式Q + 1比较大于P.在所有其他情况下,行为未定义。
但是,==
无法与p+4
进行比较,例如==
&X
,其中X
是另一个变量。这是(最好的我的C标准解密)未指定的行为。 (当然,p + N
无法与<=
到&X
进行比较。
两个指针比较相等,当且仅当两个都是空指针时,两者都是指向同一对象的指针(包括指向对象的指针和在其开头的子对象)或函数,两者都指向超过最后一个元素的指针。相同的数组对象,或者一个是指向一个数组对象末尾的指针,另一个是指向不同数组对象的开头的指针,该数组对象恰好跟随地址空间中的第一个数组对象.10)< / p>
109)两个对象在内存中可能相邻,因为它们是较大数组的相邻元素或结构的相邻成员,它们之间没有填充,或者因为实现选择放置它们,即使它们是不相关的。如果先前的无效指针操作(例如数组边界外的访问)产生了未定义的行为,则后续比较也会产生未定义的行为。
(C11 6.5.9:6)
严格来说,标准似乎并没有说p + 4 == NULL
被定义的任何地方(编辑:,正如rici所指出的那样,p + 4
唯一允许的等于q
到q
是p + 4 == NULL
是“不同数组对象的开始,恰好跟随......”。由于NULL不是任何对象的地址,因此{{1}}为假)。
This博客文章在C中查看此指针和其他指针比较。