Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weird behavior of reference to vector.back() after vector is modified

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.

like image 408
starrify Avatar asked Nov 20 '13 14:11

starrify


1 Answers

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.

like image 81
Shafik Yaghmour Avatar answered Nov 06 '22 12:11

Shafik Yaghmour