Strange behavior of a link to vector.back () after changing a vector

Let's start with this sample code in C ++:

#include <vector> #include <iostream> int main() { std::vector<int> vec; vec.push_back(0); for (int i = 1; i < 5; i++) { const auto &x = vec.back(); std::cout << "Before: " << x << ", "; vec.push_back(i); std::cout << "After: " << x << std::endl; } return 0; } 

The code is compiled with g++ test.cc -std=c++11 -O0 , and below is the result:

 Before: 0, After: 0 Before: 1, After: 0 Before: 2, After: 2 Before: 3, After: 3 

I expected the second line of output would be

 Before: 1, After: 1 

since x refers to an element in a vector that should not be changed by adding elements to the vector.

However, I have not yet read the parsed code or conducted any other investigations. Also I do not know if this behavior is undefined in the language standard.

I want this to be explained. Thanks.

+6
source share
2 answers

push_back can cause redistribution if we look at the C ++ standard project section 23.3.6.5 vector modifiers say:

void push_back (const T & x);

void push_back (T && x);

Notes: causes redistribution if the new size is larger than the old. If there is no redistribution, all iterators and references before the insertion point remains valid.

we can see that back gives us a link, so if there is a redistribution, it will be invalidated anymore.

+8
source

vector iterators (and previous links to elements) can be canceled after changing the vector. Using them is unsafe.

+4
source

Source: https://habr.com/ru/post/958484/


All Articles