Iterators and pointers pointing into an
std::vector can become invalid, but only when performing certain operations. Using invalid iterators/pointers will result in undefined behavior.
Operations which invalidate iterators/pointers include:
Any insertion operation which changes the
capacity of the
vector will invalidate all iterators/pointers:
vector<int> v(5); // Vector has a size of 5; capacity is unknown. int *p1 = &v; v.push_back(2); // p1 may have been invalidated, since the capacity was unknown. v.reserve(20); // Capacity is now at least 20. int *p2 = &v; v.push_back(4); // p2 is *not* invalidated, since the size of `v` is now 7. v.insert(v.end(), 30, 9); // Inserts 30 elements at the end. The size exceeds the // requested capacity of 20, so `p2` is (probably) invalidated. int *p3 = &v; v.reserve(v.capacity() + 20); // Capacity exceeded, thus `p3` is invalid.
auto old_cap = v.capacity(); v.shrink_to_fit(); if(old_cap != v.capacity()) // Iterators were invalidated.
Any insertion operation, which does not increase the capacity, will still invalidate iterators/pointers pointing to elements at the insertion position and past it. This includes the
vector<int> v(5); v.reserve(20); // Capacity is at least 20. int *p1 = &v; int *p2 = &v; v.insert(v.begin() + 2, 5, 0); // `p2` is invalidated, but since the capacity // did not change, `p1` remains valid. int *p3 = &v[v.size() - 1]; v.push_back(10); // The capacity did not change, so `p3` and `p1` remain valid.
Any removal operation will invalidate iterators/pointers pointing to the removed elements and to any elements past the removed elements. This includes the
vector<int> v(10); int *p1 = &v; int *p2 = &v; v.erase(v.begin() + 3, v.end()); // `p2` is invalid, but `p1` remains valid.
operator= (copy, move, or otherwise) and
clear() will invalidate all iterators/pointers pointing into the vector.