Unexpected behavior using iterators with nested vectors
c++, c++11, iterator, vector
Solution
`push_back` invalidates iterators, simple as that.
std::vector<int>::iterator foo_it = foo[0].begin();
foo.push_back(std::vector<int>(3, 2));
After this, `foo_ti` is no longer valid. Any insert/push_back has the potential to internally re-allocate the vector.
Problem
This sample program gets an iterator to an element of a vector contained in another vector. I add another element to the containing vector and then print out the value of the previously obtained iterator: ``` #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; } ``` Since the vector correspinding to `foo_it` has not been modified I expect the iterator to still be valid. However when I run this code I get the following output (also on ideone): ``` *foo_it: 1 *foo_it: 0 ``` For reference I get this result using g++ versions 4.2 and 4.6 as well as clang 3.1. However I get the expected output with g++ using `-std=c++0x` (ideone link) and also with `clang` when using both `-std=c++0x` and `-stdlib=libc++`. Have I somehow invoked some undefined behavior here? If so is this now defined behavior C++11? Or is this simply a compiler/standard library bug? Edit I can see now that in C++03 the iterators are invalidated since the vector's elements are copied on reallocation. However I would still like to know if this would be valid in C++11 (i.e. are the vector's elements guaranteed to be moved instead of copied, and will moving a vector not invalidate it's iterators).