Humam Helfawi
Humam Helfawi

Reputation: 20274

Using the address of an item in stable vector

items in std::vector are dynamically allocated and their addresses may change when a reallocation happens. So, it is not possible to depend on their addresses because it is not stable.

On the other hand, if I have a std::vector which contains some items and I do not have any intention to change anything about it during its life cycle, is it valid (well-defined) to use the addresses of its items?

Example:

std::vector<foo> foos;
foos.reserve(100);
for(size_t i=0;i<100;++i){
    foos.emplace_back(make_random_foo());
}
//From now no one can touch foos    
auto ptr_to_the_fifth_foo=&foos[4];

In other words, does the standard guarantee that noting will affect the vector items addresses since I did not do that by my self?

Upvotes: 2

Views: 173

Answers (2)

Pixelchemist
Pixelchemist

Reputation: 24946

If no member function of the std::vector is called, the vector may not be changed at all and as such the contents remain the same and all pointers stay valid.

In your example you call operator[](size_type n) which is defined in the standard as being equivalent to *(a.begin() + n).

A std::vector is a container and therefore, the container requirements hold which state:

Unless otherwise specified (either explicitly or by defining a function in terms of other functions), invoking a container member function or passing a container as an argument to a library function shall not invalidate iterators to, or change the values of, objects within that container.

Since begin() is not specified to invalidate any iterators to the container, operator[] won't either.

Upvotes: 3

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275585

Yes.

Pointers and references to elements are only invalidated when their iterator is invalidated.

Iterators are invalidated when capacity has to grow (when size passes capacity), or when you insert/remove elements before that element in the vector. They can also be invalidated when a container is moved-to or moved-from, but it might not occur.

I believe swap is specified to not invalidate iterators, but rather make them refer to the "new home" as it where (and hence, the pointers/references to the "new home" in the "new vector") (ie, the buffer ownership changes). Move-assign does not make this promise. I do not remember off the top of my head if move-construct does.

Upvotes: 1

Related Questions