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 was expecting the second line of output to be
Before: 1, After: 1
since x
is reference to an item in the vector, which shall not be modified by appending items to the vector.
However I haven't read the disassembled code or done any other investigations for now. Also I don't know whether this is an undefined behavior in the language standard.
I want this to be explained. Thanks.
push_back can cause reallocation, if we look at the draft C++ standard section 23.3.6.5
vector modifiers says:
void push_back(const T& x);
void push_back(T&& x);
Remarks: Causes reallocation if the new size is greater than the old capacity. If no reallocation happens, all the iterators and references before the insertion point remain valid.
we can see that back gives us a reference and so if there is a reallocation it will not be valid anymore.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With