C++: Are pointers to vectors (and their elements) stable, since vectors will migrate in memory to fit more elements as they grow?

Viewed 109

A pointer to a vector should stay stable during the life time of the vector. A pointer to an element in the vector is subject to change as the vector grows to accomodate more elements (and therefore has to move its contents in memory). I.e. the "header" of the vector stays where it is in memory, the content may move.

I seem to have just confirmed this empirically, I just wanted to make sure that my concept of this was accurate.

Test code:

std::vector<std::string> vec {21, "Element"};
std::vector<std::string> *ptr_v = &vec;
std::string *ptr_el = &vec.at(20);

std::cout << "Before: &vec: " << &vec << " *vec: " <<
             ptr_v << " *element 20:" << ptr_el << std::endl;

for(int i = 0; i < 100000; i++)
    vec.push_back("Element");

std::vector<std::string> *ptr_v_a = &vec;
std::string *ptr_el_a = &vec.at(20);

std::cout << "After:  &vec: " << &vec << " *vec: " <<
             ptr_v_a << " *element 20:" << ptr_el_a << std::endl;

enter image description here

1 Answers

Yes you are right, pointers or iterators at vector elements are only valid/safe to use as long as you don't perform certain operations on the vector.

Adding new elements or using resize/reserve might cause the vector to move the elements to a different location because it needs more memory to grow in size. It doesn't always happen, when a vector needs to reallocate and move it's data to a new place, it actually allocates more memory than necessary to avoid having to do it every time you add a single new item. But you should never rely on this. Always expect your pointers/iterators to be invalid once you change the vectors size. Acessing them afterwards is undefined behaviour. For the same reason adding/removing elements while going through a vector with a ranged based loop is a very bad idea.

Related