以下使用涉及越界访问的指针算法的语句是否有效?

Are the following statements using pointer arithmetic involving out of bound aceess valid?

char array[8] = "Raining";

根据我的理解,我认为以下所有针对这些陈述的评论都是真实的。

char *p1 = array + 7;      --> points to '[=11=]'

char *p2 = array + 8;      --> undefined behaviour

char *p3 = array + 9;      --> undefined behaviour

char *p4 = array + 10;     --> undefined behaviour

我的理解对吗?

在你的情况下,

  char *p1 = array + 7;

  char *p2 = array + 8;

有效,因为,法律允许您指向

  • 数组长度内的任何对象
  • 最后一个数组元素之后的一个 直到您取消引用它

OTOH,

  char *p3 = array + 9;

  char *p4 = array + 10; 

未定义。


引用 C11,章节 §6.5.6,"Additive operators"(强调我的

[ C99章节 §6.5.6/p8 相同,任何感兴趣的人]

When an expression that has integer type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the pointer operand points to an element of an array object, and the array is large enough, the result points to an element offset from the original element such that the difference of the subscripts of the resulting and original array elements equals the integer expression. In other words, if the expression P points to the i-th element of an array object, the expressions (P)+N (equivalently, N+(P)) and (P)-N (where N has the value n) point to, respectively, the i+n-th and i−n-th elements of the array object, provided they exist. Moreover, if the expression P points to the last element of an array object, the expression (P)+1 points one past the last element of the array object, and if the expression Q points one past the last element of an array object, the expression (Q)-1 points to the last element of the array object. If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined. [...]

由于 NULL 终止符,

array 中有 8 个元素。

char *p1 = array + 7; 定义明确。

char *p2 = array + 8;实际上是定义的。您可以设置一个指向数组的指针。 (只是不要取消引用它。)

另外两个未定义。不允许将指针设置为超出数组的一个。

第一行指向数组内的一个合法元素,第二行在解引用前一直有效。你剩下的 post 是对的。

char *p1 = array + 7;   \-->points to '[=10=]', within array

char *p2 = array + 8;   \-->defined behaviour until dereferenced 

允许尾后寻址的原因是为了便于编写遍历整个数组的循环,例如,while (*d++ = *s++);.

数组的边界标记描述了一个半开范围,从(并包括)第一个元素开始,到(但不包括)最后一个元素结束:[beginning,end)