在c++中,对于数组类型,解引用一个指向超出末尾的指针是否有定义?
考虑以下代码:
#include <cassert>
#include <iterator>
int main()
{
// An array of ints
int my_array[] = { 1, 2, 3 };
// Pointer to the array
using array_ptr_t = int(*)[3];
array_ptr_t my_array_ptr = &my_array;
// Pointer one-past-the-end of the array
array_ptr_t my_past_end = my_array_ptr + 1;
// Is this valid?
auto is_this_valid = *my_past_end;
// Seems to yield one-past-the-end of my_array
assert(is_this_valid == std::end(my_array));
}
普遍认为,对一个指向末尾后的位置的指针进行解引用是未定义的行为。但是,对于数组类型的指针是否也适用这一点呢?
从纯粹的指针算术角度来看,似乎这应该是有效的,因为
*my_past_end
会产生一个指向数组中 将会 存在的第一个元素的指针,这也恰好是原始数组my_array
的一个有效的末尾后位置的int*
。然而,另一种看待这个问题的方式是,
*my_past_end
正在生成一个引用到一个不存在的数组,这个引用隐式转换为一个int*
。这个引用似乎令人不安。提供上下文,我的问题是由这个问题引发的,具体来说是这个答案的评论。
编辑:这个问题并非Take the address of a one-past-the-end array element via subscript: legal by the C++ Standard or not?的重复。我问的是这个规则是否也适用于指向数组类型的指针。
编辑2:删除了
auto
来明确说明my_array_ptr
不是一个int*
。
my_array_ptr
是指向整个数组的指针,而不是第一个元素。它是int(*)[3]
而不是int *
。 - François Andrieux