Reputation: 20274
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
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
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