根据n4296,第5.7 / 4节
此外,如果表达式
P
指向数组对象的最后一个元素,则表达式(P)+1
指向数组对象的最后一个元素,如果表达式Q
将一个指向数组对象的最后一个元素,表达式(Q)-1
指向数组对象的最后一个元素。如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出;否则,行为未定义。
在C ++中,指针指向一个超过数组最后一个元素的指针并在指针算术中使用它是非常好的:
int a[5], *p = a+5;
std::ptrdiff_t d = p-a; // Guaranteed to be 5
即使来自容器的迭代器也支持这种行为:
std::vector<int> vec(5);
std::ptrdiff_t diff = vec.end()-vec.begin(); // Guaranteed to be 5
我的问题是,这适用于动态分配的内存吗?请考虑以下示例:
案例1:new
int *a = new int, p = a+1;
std::ptrdiff_t diff = p-a; // Well-defined?
delete a;
案例2:new[]
int *a = new int[5], p = a+5;
std::ptrdiff_t diff = p-a; // Well-defined?
delete[] a;
我认为案例1是UB而案例2是明确定义的。但是ISO 14882标准究竟是什么定义的?