Search code examples
listmemorystlmemory-leakserase

Deleting objects in an stl list using the erase function in c++


So I'm trying to implement some memory management techniques here. In my program, I created an stl list so that it would contain objects of the class "Blast" with it's respective iterator:

list<Blast> blasts;
list<Blast>::iterator it1;

I've looked around and found that if you use the erase function, it will call the destructor of the class, and then delete the iterator to which it points to the object and return some other pointer (iterator). However, if the class is a POD, then the call for the destructor won't do anything, hence all the information that was saved in that object will be kept in memory.

To go around this, I tried to allocate the object dynamically so that I could use the delete function to wipe it out of memory as such:

Blast *blast;
blast = new Blast;

However, here I encountered a problem. When i tried to push the object onto the list, it only lets me push the pointer:

blasts.push_back(*blast);

At first, I didn't think anything about it. So I continued:

if(it2->getX() > 600) {

   delete &it2;
   it2 = blasts.erase(it2);

   }

I realized then, that what this does is that it erases the pointer that was pointing to the object, and then the pointer that was pointing to the pointer pointing to the object.

I'm not entirely sure if that is actually correct, as I have no way of knowing if there's a memory leak. So my question is this:

What do I have to do to erase the object from memory BEFORE deleting whatever pointer is pointing to that object? Is my implementation correct? Is it's result the same as if I were to just simply push the object onto the list?


Solution

  • then delete the iterator to which it points to the object and return some other pointer (iterator)

    Not a pointer, an iterator.

    hence all the information that was saved in that object will be kept in memory.

    No, that's not true.

    When i tried to push the object onto the list, it only lets me push the pointer:

    Huh? If you have a std::list<Blast> then of course you can't store a Blast* in the list, that's not the same type. Maybe you want to change the list to a std::list<Blast*>?

    delete &it2;

    This is wrong, it tries to delete the iterator, not the list element it refers to. To delete the element it points to you want:

    delete &*it2;
    

    But if you still have a std::list<Blast> then that will try to delete an object owned by the list, which would be very wrong and cause bugs.

    I think you should just stick to std::list<Blast> and forget this entire question - it seems to be based on a misunderstanding that erasing an element doesn't destroy the object, which is not true. If your problem is that Blast objects have pointer members that point to dynamically allocated memory then add a destructor to Blast to make it clean up properly.