如果我在C中递增NULL
指针,那会发生什么?
#include <stdio.h>
typedef struct
{
int x;
int y;
int z;
}st;
int main(void)
{
st *ptr = NULL;
ptr++; //Incrementing null pointer
printf("%dn", (int)ptr);
return 0;
}
输出:
12
是未定义的行为?如果否,则为什么?
行为总是不确定的。您永远无法在null上拥有内存。
指针算术仅在数组中有效,您可以将指针设置为数组索引或最终元素以外的一个位置。请注意,我说的是在这里设置指针,而不是提取指针。
您还可以将指针设置为标量和过去的标量。
您不能使用指针算术来穿越自己拥有的其他内存。
是的,它会导致不确定的行为。
任何操作员都需要一个"有效"操作数,NULL
不是邮政增量运算符的操作数。
引用 C11
,第§6.5.2.4
后缀
++
操作员的结果是操作数的值。作为副作用, 操作数对象的值是增加的(即适当类型的值1是 添加到它(。[....]
和与加性操作员有关的,§6.5.6
添加,两个操作数均应具有算术类型,或者一个操作数应为一个 指向完整对象类型的指针,另一种应具有整数类型。(增量是 等效于添加1。(
然后,p7,
[...]指向不是一个元素的对象的指针 阵列的行为与指向长度的第一个元素的指针相同 对象的类型为其元素类型。
和P8,
如果指针操作数指向 数组对象,并且数组足够大,结果指向元素偏移 原始元素使得结果和原始的下标的差异 阵列元素等于整数表达式。换句话说,如果表达式
P
指向 数组对象的i
-元素,表达式(P)+N
(等效地,N+(P)
(和(P)-N
(其中N
具有值n
(分别指向i+n
-TH和i−n
-的TH -TH元素 数组对象,只要它们存在。[....]如果两个指针 操作数和相同数组对象元素的结果,或一个超过最后一个的元素 数组对象的元素,评估不会产生溢出;否则 行为不确定。
我认为PTR将指向struct st
的第二个数组成员(好像有(。那就是ptr++
所做的。最初指针为0或NULL
。现在是12(3 * sizeof(int)
= 3*4 = 12(。
在您的示例中,您没有将指向其指向地址的指针删除。当您踩下指针时,它的大小将被递增。只需尝试:
printf("Test: %lu", sizeof(st));
您将获得Test: 12
作为输出。如果您将其解释,例如*ptr
,它将导致未定义的行为。