std::deque迭代器可指向begin之前吗?相关代码是否为未定义行为?
问题解答
原代码的行为:未定义行为
你给出的代码存在未定义行为,因为对std::deque的起始迭代器begin()执行--it操作,已经超出了该迭代器的合法取值范围。
C++标准规定,随机访问迭代器(std::deque、std::vector的迭代器都属于这类)的合法区间是[begin(), end()]——即要么指向容器内的某个元素,要么指向尾后位置(end())。任何让迭代器移动到begin()之前,或者end()之后的操作,无论是否解引用该迭代器,都是未定义行为。
所以代码里的--it、it < arr.begin()、arr.begin() - it == 1这些操作,都没有标准保证的行为,编译器可以产生任何结果,甚至直接崩溃。
关于迭代器超出合法范围的常见容器规则
1. std::vector 和 std::deque(随机访问迭代器)
- 合法迭代器仅存在于
[begin(), end()]区间内。 - 移动迭代器到
begin()之前,或者end()之后的任何操作(比如--begin()、++end())都是未定义行为,哪怕不进行解引用。 - 注意:尾后迭代器
end()本身是合法的,但对它执行递增操作(++end())就越界了,属于未定义行为。
2. std::list(双向迭代器)
std::list的迭代器是双向迭代器,不支持随机访问(不能用<比较,也不能做减法)。- 同样,合法迭代器区间是
[begin(), end()]。对begin()执行--,或者对end()执行++,同样属于未定义行为。
总结
所有标准容器的迭代器,都只保证[begin(), end()]区间内的操作是合法的。超出这个区间的迭代器移动、比较、算术运算,无论是否解引用,均属于未定义行为,没有任何标准层面的保证。
内容的提问来源于stack exchange,提问作者tmlen
相关产品推荐
相关产品推荐

