假设我有一个for循环,它使用如下指针在数组中存储零:
int *vp, values[5];
for(vp = &values[5-1]; vp >= &values[0]; vp--)
*vp = 0;
Run Code Online (Sandbox Code Playgroud)
书中的指针表示这个循环存在问题,因为比较vp >= &values[0]未定义,因为它超出了数组的范围.但是怎么样?
假设一个指针相当于一个无符号整数,我们可以看到,只有从values地址 0 开始才会出现这个问题,在这种情况下,指针在递减后会回绕,变成UINT_MAX。
为了直观地说明问题,让我们逐步了解所发生的情况,假设values从地址 0x0 开始:
iteration 1:
vp = 0x4, *vp = 0;
iteration 2:
vp = 0x3, *vp = 0;
iteration 3:
vp = 0x2, *vp = 0;
iteration 4:
vp = 0x1, *vp = 0;
iteration 5:
vp = 0x0, *vp = 0;
iteration 6:
vp = 0xFFFFFFFF; *vp = ?? // uh oh!
Run Code Online (Sandbox Code Playgroud)
因此,vp永远不会小于指针的最小值(即 0),并且会导致无限循环(假设所有内存都是可写的)或分段错误。
根据标准,这也是未定义的行为(因为您可以在数组之后寻址一个元素,但不能在数组之前寻址),但实际上,这在任何实际系统上都不会失败。