此示例程序获取另一个向量中包含的向量元素的迭代器。我将另一个元素添加到包含向量,然后打印出以前获得的迭代器的值:
#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
的向量,我希望迭代器仍然有效。但是,当我运行此代码时,我得到以下输出(也在ideone上):
*foo_it: 1
*foo_it: 0
作为参考,我使用g ++版本4.2和4.6以及clang 3.1获得此结果。但是,当使用-std=c++0x
和clang
时,我使用-std=c++0x
(ideone link)和-stdlib=libc++
获得g ++的预期输出。
我在这里以某种方式调用了一些未定义的行为吗?如果是这样,现在定义的行为C ++ 11?或者这只是一个编译器/标准库错误?
编辑我现在可以看到,在C ++ 03中,迭代器无效,因为在重新分配时复制了向量的元素。但是我仍然想知道这在C ++ 11中是否有效(即向量的元素保证被移动而不是复制,并且移动向量不会使它的迭代器无效)。
答案 0 :(得分:5)
push_back
使迭代器失效,就像那样简单。
std::vector<int>::iterator foo_it = foo[0].begin();
foo.push_back(std::vector<int>(3, 2));
在此之后,foo_ti
不再有效。任何insert / push_back都有可能在内部重新分配向量。
答案 1 :(得分:5)
由于未对
foo_it
的矢量进行修改
错误。 push_back
销毁了与foo_it
对应的向量。 <{1}}被销毁后foo_it
无效。
答案 2 :(得分:0)
我猜错误的感觉是那个矢量&lt;矢量&lt; int&gt; &GT;是指针的向量,当外部指针被重新分配时,指向内部的指针仍然有效,这对于** int是正确的。但是,重新分配向量也会重新分配所有内部向量,这使得内部迭代器也无效。