C 正在计算指向对象以外的指针';存储未定义?

C 正在计算指向对象以外的指针';存储未定义?,c,pointers,c11,C,Pointers,C11,考虑一下代码片段: int main(void) { int i = 42; int *p = &i; ++p; // Is this pointer evaluation undefined? *p = 5; // How about this? return 0; } ++p中指针的计算格式不正确 C标准(C11,6.5.6)允许计算指向数组对象过去一端的指针?这也适用于非数组对象吗?否。上述程序中的++p定义良好。但*p=5导致出现错误 C标准规

考虑一下代码片段:

int main(void)
{
   int i = 42;
   int *p = &i;

   ++p; // Is this pointer evaluation undefined?
   *p = 5; // How about this?

   return 0;
}
++p
中指针的计算格式不正确


C标准(C11,6.5.6)允许计算指向数组对象过去一端的指针?这也适用于非数组对象吗?

否。上述程序中的
++p
定义良好。但
*p=5导致出现错误

C标准规定

C11草案,6.5.6加法运算符,第7页

在这些运算符中,指向以下对象的指针: 数组中的元素的行为与指向第一个元素的指针的行为不同 长度为1的数组的元素,其对象类型为 元素类型

允许我们考虑<代码> int i/代码>为<代码> int i(1);<代码>当对对象

i
和6.5.6执行指针运算时,第8页如下:

[…]如果指针操作数和结果都指向 相同的数组对象,或超过数组最后一个元素的一个 对象时,评估不应产生溢出;否则 行为是未定义的。如果结果指向最后一个元素上方的一个 对于数组对象,它不能用作一元
*
要计算的运算符

因此,无论
&i+1
是否是一个对象数组,
&i+1
的求值在C中都有很好的定义。但是,取消对其的引用未定义:

int i = 9;
int *p = &i + 1; // Only pointer evaluation done here. Well-defined.
int x = *(p-1); // well defined. p-1 is should be equal to &i as required by 6.5.6, p8
*p = 42; // ill-formed.

int arr[5];
int *q = arr+5; // well-defined. Evaluating one past the end of an array.
*q = 42; //This is undefined.
int i = 9;
int *p = &i;

++p; // This is OK. Evaluation is allowed.
*p = 5; // This is undefined. Not allowed to de-reference the pointer one past the end.
++p; // This is undefined. `p` now points to two past the end of the object after increment.
*p = 5; // This is undefined.
但是,这仅适用于阵列的过去一端。例如,下面的第二个增量未定义:

int i = 9;
int *p = &i + 1; // Only pointer evaluation done here. Well-defined.
int x = *(p-1); // well defined. p-1 is should be equal to &i as required by 6.5.6, p8
*p = 42; // ill-formed.

int arr[5];
int *q = arr+5; // well-defined. Evaluating one past the end of an array.
*q = 42; //This is undefined.
int i = 9;
int *p = &i;

++p; // This is OK. Evaluation is allowed.
*p = 5; // This is undefined. Not allowed to de-reference the pointer one past the end.
++p; // This is undefined. `p` now points to two past the end of the object after increment.
*p = 5; // This is undefined.

p++
是可以的,但是
p++
之后会再次导致UB。一个超越终点的人是一个特殊的人case@MattMcNabb我想把它改成
++p
会更清楚。我会编辑。到目前为止,我已经收到两张反对票。如果问题有问题,请告诉我,我会改进。
*p
正在取消对无效指针的引用,因此是的,它的行为是未定义的。你提到的C标准中的这一段涉及计算到一个无键指针的表达式,它没有提到去引用那个指针,因为它总是bad@EliasVanOotegem否。它确实说明了取消对越界指针的引用:如果结果指向数组对象最后一个元素的上方,它不能用作一元*运算符的运算对象。回答得好。对于C++,这是一样的吗?我还没有检查C++标准。但我认为就我所知,这是一样的。@CoolGuy基本上,是的。C++11并没有严格地说,
*p=5
是未定义的,如果已知
p
持有另一个对象的地址,但我认为C++14再次规定了这一点,因为基本点是,如果指向的对象位于内存的末尾,那么指向它之外的对象将不会指向地址0x00000。。。因此,很明显,这个对象最多放在内存的末尾-1。