C++ 迭代器结束检查在`for`循环内递增后失败

C++ 迭代器结束检查在`for`循环内递增后失败,c++,c++11,iterator,C++,C++11,Iterator,这个问题很可能是重复的,但我在这个问题上没有发现任何东西 为什么递增放置在向量中最后一个位置的迭代器会使其不等于向量.end() 或者,换句话说,为什么会正常执行: int main() { vector<string> vec = {"ve"}; for (auto it = vec.begin(); it != vec.end(); it++) {} return 0; } 因此,it实际上是递增的,因此它的内容变为空(根据调试器进行了优化),但它并

这个问题很可能是重复的,但我在这个问题上没有发现任何东西

为什么递增放置在
向量中最后一个位置的
迭代器
会使其不等于
向量.end()

或者,换句话说,为什么会正常执行:

int main() {
    vector<string> vec = {"ve"};

    for (auto it = vec.begin(); it != vec.end(); it++) {}

    return 0;
}

因此,
it
实际上是递增的,因此它的内容变为空(根据调试器进行了优化),但它并不等于
vec.end()
。为什么?

您正在检查
它!=vec.end()
但是由于
it++
发生两次,每次检查都会跳过两次。换句话说,您正在运行通过
向量的末尾,而没有发现它

如果向向量中再添加一个元素,那么循环将到达终点并停止,因为不再跳过终点(显然这不是一个“正确”的修复,它只是演示了问题)


要修复它,请在循环中的增量之前检查end。您还可以使用
操作符Imagine
it
指向
vec.end()
之前的一个操作符进行检查,这可能是
for
循环的最后一次迭代

  • it!=vec.end()
    将为
    true
    ,因此循环将继续
  • it++
    it==vec.end()
    now
  • 执行
    for
    循环头的
    it++
    it
    指向一个之外的
    vec.end()
  • vec.end()
    vec.end()+1
    it
    的最终值)超出
    vec
    的最后一个元素两个,这是未定义的行为


    这意味着取消对迭代器的引用将访问未分配的内存(解释分段错误)。再次未定义行为。

    在for循环中,迭代器上的增量操作是循环中的最后一个(隐式)操作

    案例1:循环以“it”=vec.begin()开始。什么也没发生。“it”是递增的(隐式的)。it=vc.end()。循环结束。这就是正常的行为

    案例2:循环以it=vec.begin()开始。“it”是递增的。it=vc.end()。“it”再次递增(隐式)。“它”移动到下一个内存位置,并在每个周期中不断增加。因此,无限循环


    案例3:循环以it=vec.begin()开始。如果它==vc.end(),则执行检查。返回false。打印“it”引用的内存位置中的值。“it”是递增的。it=vc.end()。“it”再次递增(隐式)。“它”移动到下一个未分配的内存位置。因此,SEG错误。

    侧注:当你不使用结果时,不要在C++中使用后缀增量来增加非POD类型(更容易:即使是POD类型,也总是使用前缀增量/减量,这样就不会在非POD类型中出错)。后缀增量/减量涉及复制构造(以及最终销毁),其中前缀增量/减量可以就地修改并便宜地返回引用。
    int main() {
        vector<string> vec = {"ve"};
    
        for (auto it = vec.begin(); it != vec.end(); it++) { it++; }
    
        return 0;
    }
    
    int main() {
        vector<string> vec = {"ve"};
    
        for (auto it = vec.begin(); it != vec.end(); it++) {
            cout << (it == vec.end()) << " ";
            cout << (*it == "ve") << endl;
            it++;
        }
    
        return 0;
    }
    
    0 1
    0