如果我在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("%d\n", (int)ptr);
return 0;
}
输出:
12
未定义的行为?如果否,那么为什么?
答案 0 :(得分:6)
行为始终未定义。你永远不能拥有NULL的内存。
指针算法仅在数组中有效,您可以设置指向数组索引的指针或指向最终元素之外的一个位置。注意我说的是在这里设置一个指针,而不是取消引用它。
您还可以设置指向标量的指针和标量之前的指针。
您不能使用指针算法来遍历您拥有的其他内存。
答案 1 :(得分:5)
是的,它会导致undefined behavior。
任何运算符都需要一个“有效”操作数,NULL
不是后增量运算符的一个。
引用C11
,chapter §6.5.2.4
后缀
++
运算符的结果是操作数的值。作为副作用, 操作数对象的值递增(即,相应类型的值为1 添加到它)。 [....]
并与加法运算符相关,§6.5.6
另外,两个操作数都应具有算术类型,或者一个操作数应为a 指向完整对象类型的指针,另一个指针应具有整数类型。 (递增是 相当于添加1。)
然后,P7,
[...]指向不是元素的对象的指针 数组的行为与指向长度为1的数组的第一个元素的指针相同 对象的类型作为其元素类型。
和,P8,
如果指针操作数指向的元素 一个数组对象,并且该数组足够大,结果指向一个偏移的元素 原始元素使得结果和原始的下标不同 数组元素等于整数表达式。换句话说,如果表达式
P
指向 数组对象的i
- 元素,表达式(P)+N
(等效地,N+(P)
)和(P)-N
(其中N
的值为n
)分别指向i+n
- 和i−n
- 元素 数组对象,只要它们存在。 [....]如果两个指针 操作数和结果指向同一个数组对象的元素,或者指向最后一个数组对象的元素 数组对象的元素,评估不得产生溢出; 否则, 行为未定义。
答案 2 :(得分:0)
在您的示例中,您没有取消引用刚刚打印出指向的地址的指针。当您步进指针时,它将以其引用类型的大小递增。试试吧:
printf("Test: %lu", sizeof(st));
您将获得Test: 12
作为输出。如果您取消引用它,例如*ptr
,则会导致未定义的行为。
答案 3 :(得分:0)
我认为ptr将指向struct st
的第二个数组成员(就好像有)。这是ptr++
的作用。最初指针位于0或NULL
。现在是12(3 * sizeof(int)
= 3 * 4 = 12)。