Question

I basically have a

vector<Object> vec_; 

as a class member in a cpp class. At a certain class function this vector will be filled with "Objects" just like this:

vec_.push_back(Object());

At a later time I iterate through the vector elements and keep a pointer to the best element. Then the vector is cleared as shown in the following:

Object* o_ptr = &(vec_[0]);
for (unsigned int i = 1;  i < vec_.size(); i++) {
  if (o_ptr->getCost() > vec_[i].getCost()) {
  o_ptr = &(vec_[i]);
} 

vec_.clear();

Now my question is: What happens to the objects removed from the vector? Is their lifetime over as soon as the they are removed from the vector? And does the pointer also point to empty space then? And if not when does the lifetime of these objects end?

Regards scr

Was it helpful?

Solution

What happens to the objects removed from the vector?

They are destructed.

Is their lifetime over as soon as the they are removed from the vector?

Yes.

Does the pointer also point to empty space then?

Yes it does. If you want to save the object, make a copy of it before clearing the vector.

It's also important to note that certain vector operations might leave pointers pointing to nothing even if the vector is not cleared. Specifically resizes, which typically involve a reallocation. It's generally best to store references to vector elements by index, since you will always be able to get the element via the index (whereas a pointer may be invalidated after certain operations).

The subscript operator, applied to vectors, returns a reference and does not make a copy.

OTHER TIPS

When vector.clear() is called (or when the vector is destructed) all objects contained with the vector will be destructed (as in this case they are objects and not raw pointers), leaving o_ptr as a dangling pointer.

Note that caching the address (or iterator) of an element in vector is dangerous, even without a call to clear(). For example, push_back() could result in internal reallocation of the vector, invalidating the cached address (or iterator).

The objects are owned by the vector and .clear() indeed removes them.

In addition, pointing to the objects stored in a std::vector is a bit dangerous. If you push new elements to the vector, at some point the vector might need to allocate more memory - which is likely to copy all the previous elements to a different address using their copy constructor (hence invalidating your pointers).

So: Use integer indices with std::vector instead of pointers, unless you know that you won't be pushing beyond the reserved capacity (which you can assure using .reserve()).

(Also while we're at it, make sure not to confuse the vector's internal buffer size with .size(), which is simply the number of actual elements stored).

The best way to track the lifetime of an object is to add a printf to both the constructor and destructor.

class MyObject
{
public:
    MyObject()
    {
        printf("MyObject constructed, this=%p\n", this);
    }
    ~MyObject()
    {
        printf("MyObject destructed, this=%p\n", this);
    }
};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top