c++ - 使用带嵌套 vector 的迭代器的意外行为

标签 c++ vector iterator c++11

此示例程序获取一个迭代器,该迭代器指向包含在另一个 vector 中的一个 vector 的元素。我将另一个元素添加到包含 vector 中,然后打印出先前获得的迭代器的值:

#include <vector>
#include <iostream>

int main(int argc, char const *argv[])
{
    std::vector<std::vector<int> > foo(3, std::vector<int>(3, 1));
    std::vector<int>::iterator foo_it = foo[0].begin();
    std::cout << "*foo_it: " << *foo_it << std::endl;
    foo.push_back(std::vector<int>(3, 2));
    std::cout << "*foo_it: " << *foo_it << std::endl;
    return 0;
}

由于对应于 foo_it 的 vector 没有被修改,我希望迭代器仍然有效。但是,当我运行此代码时,我得到以下输出(也在 ideone 上):

*foo_it: 1
*foo_it: 0

作为引用,我使用 g++ 版本 4.2 和 4.6 以及 clang 3.1 得到了这个结果。但是,我使用 -std=c++0x ( ideone link ) 以及使用 -std=c+ 时的 clang 获得了预期的输出+0x-stdlib=libc++

我是否以某种方式在这里调用了一些未定义的行为?如果是这样的话,这是现在定义的行为 C++11 吗?或者这只是一个编译器/标准库错误?

编辑 我现在可以看到在 C++03 中迭代器是无效的,因为 vector 的元素在重新分配时被复制。但是我仍然想知道这在 C++11 中是否有效(即 vector 的元素是否保证移动而不是复制,并且移动 vector 不会使其迭代器无效)。

最佳答案

push_back 使迭代器无效,就这么简单。

std::vector<int>::iterator foo_it = foo[0].begin();
foo.push_back(std::vector<int>(3, 2));

在此之后,foo_ti 不再有效。任何 insert/push_back 都有可能在内部重新分配 vector 。

关于c++ - 使用带嵌套 vector 的迭代器的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10368741/

相关文章:

c# - 如何避免 Iterator 方法被重启?

c# - 字符串 "abc"在通过命名管道从 C++ 到 C# 作为 Unicode 后变为 "a\0b\0c\0"

python - 在 Python 中创建一组向量的笛卡尔积?

c++ - 遍历 vector 并删除其某些元素的安全方法是什么

c++ - 如何在 "std::vector<char>"容器中查找单个单词

C++模板类映射

c++ - <T::* int> 是什么意思?

c++ - 具有值和指针的数组

C++ 重载运算符 []

c# - 我是否需要重写我的异步方法/类来实现我想要的功能?