c++qtcopyqvector

operator[] of QVector returns incorrect value


There are 4 examples of QVector and operator=:

auto value1 = (QVector<int>() << 1)[0]; //value is 1 (correct)
auto &value2 = (QVector<int>() << 1)[0]; //value is -572662307 (incorrect)
const auto value3 = (QVector<int>() << 1)[0]; //value is 1 (correct)
const auto& value4 = (QVector<int>() << 1)[0]; //value is -572662307 (incorrect)

So, could you, please, explain these examples more clearly? As far as I get the idea it is something about "deep copy", which is created by one of operator=, but it's not fully clear for me.


Solution

  • Deep copy has nothing to do with it. Copy on write mechanism (this is related to "deep copy") of QVector is completely transparent to you and doesn't impact your scenario. For now ignore this feature.

    First of all take a look what is returned by QVector::operator[]. It returns reference to element of QVector.

    Now when you use & you are capturing reference to vector item.

    Now QVector<int>() is a temporary object which live scope is limited to that line. So just after semicolon, vector is destroyed and reference is pointing to none existing element of vector (since vector doesn't exists anymore).

    This leads to undefined behavior and your bad luck didn't lead to an application crash.

    One way to fix it is not to use temporary object.

       QVector v;
       v << 1;
       auto value1 = v[0];
       auto &value2 = v[0];
       const auto value3 = v[0];
       const auto& value4 = v[0]; 
    

    Now all references are pointing to values which are still alive.