Home > Mobile >  reference_wrapper: Is this UB?
reference_wrapper: Is this UB?

Time:01-23

I'm curious if this code is UB.

https://wandbox.org/permlink/nU0iPLCrPXwQ7Kor

The code does not crash (in both GCC and Clang, with or without optimization), which makes me more and more baffled..

#include <list>
#include <vector>
#include <iostream>
#include <utility>
#include <queue>
using namespace std;


int main() {
    deque<int> l {1, 2, 3, 4, 5};
    vector<reference_wrapper<int>> v (l.begin(), l.end());
    // v now holds references to 1, 2, 3, 4, 5 in l

    cout << v[3] << '\n'; // 4

    l.pop_front();    // 1 popped

    for (auto num : l) {
        cout << num << ' '; // 2 3 4 5 
    }
    cout << '\n';    

    cout << v[0] << '\n';  // I think this should crash because 1 is dangling reference

    l.pop_front();  // 2 popped

    for (auto num : l) {
        cout << num << ' '; // 3 4 5
    }

    cout << '\n';    

    cout << v[1] << '\n';  // I think it should crash but it still outputs 2
}

CodePudding user response:

The reason why your code does not crash is because you get lucky with regards to implementation details of deque.

A deque allocates memory in blocks of 512 byte. The first and last block in a deque can be partially filled at their front or back, respectively. Pointers mark these locations. A pop_front simply moves that pointer one element forward, as long as the first block does not become completely empty.

In your example, the complete content fits into one block. So you simply keep referencing memory that remains allocated and is just considered empty by the deque. Of course any operation such as push_front or any other resize may change that.

CodePudding user response:

I'm curious if this code is UB.

Yes this is clearly undefined behavior due to using a dangling reference.

Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior.

So the output that you're seeing is a result of undefined behavior. But as i said don't rely on the output of a program that has UB. The program could have resulted in segmentation fault.

The first step to make the program correct would be to remove UB. Then and only then you can start reasoning about the output of the program.


1For a more technically accurate definition of undefined behavior see this where it is mentioned that: there are no restrictions on the behavior of the program.

  •  Tags:  
  • Related