C++中从数组中间指针进行负索引是否为定义行为?
C++数组负索引的安全性问题
我出于某些原因需要给数组两端设置“防护区”,编写了如下代码。我想知道上述语法是否安全?我知道负索引通常属于未定义行为,但该特例情况是否如此?buffer[-1]是否始终等价于padded_buffer[63]?
#include <iostream> using namespace std; const int BUFSIZE = 1 << 20; char padded_buffer[64 + BUFSIZE + 64]; char* buffer = padded_buffer + 64; int main() { buffer[-1] = '?'; // is that always equivalent to padded_buffer[63] = '?' ? cout << padded_buffer[63] << "\n"; return 0; }
这种写法是安全的,buffer[-1]始终等价于padded_buffer[63],不属于未定义行为。
原因在于C++的下标运算本质:a[b]完全等价于*(a + b)。这里的buffer是padded_buffer + 64,所以buffer[-1]就是*(buffer - 1),也就是*(padded_buffer + 64 - 1),即*(padded_buffer + 63),对应数组下标就是padded_buffer[63]。
关键是buffer - 1仍然指向padded_buffer数组的合法元素范围内(数组索引从0到64+BUFSIZE+64-1,63显然在这个区间内),所以这种指针运算和解引用都是符合标准的,没有未定义行为。
需要注意的是,负索引并非绝对安全:只有当指针偏移后仍然指向原数组(或数组末尾的一个合法位置)时,这种操作才合法。如果指针原本不指向数组元素,或者偏移后超出数组存储范围,那才会触发未定义行为。
内容的提问来源于stack exchange,提问作者Huy Le
相关产品推荐
相关产品推荐

