Monday, January 25, 2016

Lifetime of Reference to vector element in C++

This post is about using const or non const reference to an object, and its lifetime upon the object's destruction. Especially when that object is a vector element.

This is an example source code:

std::vector& CarList; //global or a member in Carz class
void Carz::DoSomethingWithTheVector(){
  if(CarList.size() > 0)
    const  Car& cref = CarList[0]; // Code #1
    MarketCar(cref); //deletes CarList[0] if car gets sold.
    AddCarToSoldList(cref); //Code #3
    //Consider all cars as sold.
   //Calculate Sale amount

void Carz::MarketCar(const Car& c)
  //market car
    //remove car from the list. 
    CarList.erase(CarList.begin()); // oops.  Code #2

In the example above, since the reference points to the first element in the CarList, if the
1. First element gets deleted or
2. The List is sorted or rearranged in any way

and the reference is used after that,
the reference will not refer to the deleted memory.

It would indeed refer to the first element in the vector, which could be the second element after the first element gets deleted, or invalid memory if the vector became empty in MarketCar.

Though the reference is a const reference, that does not copy the first element and create a temporary memory. It is still a reference. Always pointing to the first element of the array.

Hence in the above code, the memory pointed to by cref, which is sent as parameter to AddCarToSoldList() will not be the first element of the array, but the second one, or invalid memory if vector is empty.

If any element is emplaced to the front of the vector, the cref would still point to first element of the list, now the newly added element.

Reference cref does not point to the deleted memory of the first element of the vector. Just rephrasing above point.

This might be a well known issue, that everyone knows but might have forgotten. Hoping this might help developers to follow the memory trace carefully. Hence blogging about it anyways.

No comments: