c++ - 遍历动态 vector 时 auto 的异常行为

标签 c++ c++11 vector iterator auto

我正在使用自动遍历 vector (附加代码)。在遍历的同时,我还在后面附加了一些元素。我没想到会得到这样的输出。

#include <iostream>
#include <vector>
using namespace std;

vector <int> dynamic_vector;

void access( )
{
    for ( auto i : dynamic_vector ) {
        if ( i == 3 ) {
            dynamic_vector.push_back( 4 );
            dynamic_vector.push_back( 5 );
        }
        cout << i << endl;
    }
}

int main() {
    dynamic_vector.push_back( 1 );
    dynamic_vector.push_back( 2 );
    dynamic_vector.push_back( 3 );
    access( );
    return 0;
}

输出:

1
2
3

我原以为从 1 到 5 的所有数字都会被打印出来。我无法理解如何使用 auto 进行遍历?

最佳答案

除了songyuanyao的回答指出的问题外,你给出的代码是undefined behavior。首先,可能因为 push_back 需要重新分配 vector,然后所有迭代器都无效,因此递增循环变量是未定义的行为。

查看the documentation for push_back :

If the new size() is greater than capacity() then all iterators and references (including the past-the-end iterator) are invalidated. Otherwise only the past-the-end iterator is invalidated.

,我会说在基于范围的 for 语句中附加到 vector 在任何情况下都是未定义的行为,因为结束迭代器总是无效的。基于范围的 for 存储初始 end() 迭代器的拷贝,并且此迭代器在第一个 push_back 之后失效。这与您的输出匹配,因为它仍然指向三元素 vector 的原始端。但是,您不应依赖此行为。

不幸的是,我在标准中找不到“无效迭代器”语义的严格定义。 §24.2.1.11 说无效的迭代器可能是单数的,但只说明取消引用它们可能是未定义的行为。没有比较它们的语义,但考虑到 vector 的一种实现是使用内部存储之后的下一个内存地址,并且当 vector 重新分配时该地址发生变化,我会说循环是未定义的行为。

关于c++ - 遍历动态 vector 时 auto 的异常行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31310175/

相关文章:

c++ - sqlite3 事务和 exec 调用

c++ - 需要向三维数组中插入1-100的随机数

C++ 原子和跨线程可见性

c++ - 我可以使用 ' == ' 来比较两个 vector 吗?我试过了,似乎工作正常。但我不知道它是否适用于更复杂的情况

c++ - 如何重载析构函数?

c++ - 如何在类中的其他 vtable 指针中选择 vtable 指针?

c++ - 如何将函数传递给模板函数 A,该函数可能具有基于 A 的另一个参数的不同签名?

c++ - 涉及字符串输入和字符串比较的scanf问题

arrays - Matlab:如何使 [1 3 5] 变为 [1 nan 3 nan 5]

c++ - 动态内存分配,C++