Search code examples
c++pointersmemory-managementstdlist

Deleting data that is pointed to by multiple lists?


I have a an object that will potentially end up in multiple lists.

For example

std::list<object*> lista = new std::list<object*>();
std::list<object*> listb = new std::list<object*>();

object* obj = new object();
lista->push_front(obj);
listb->push_front(obj);

Potentially, there are many objects that will end up in both lists in the same way. I realize smart pointers would be the easy thing to do, but call me a masochist - I'd prefer to figure out how to do it without.

Currently, I'm trying this technique:

td::list<object*>::iterator iter;
for(iter = lista->begin(); iter != lista->end(); iter++) {
    delete (*iter);
    *iter = 0;
}

std::list<object*>::iterator iterB;
for(iterB = listb->begin(); iterB != listb->end(); iterB++) {
    if(*iterB != 0) {
        delete (*iterB);
        *iter = 0;
    }
}

delete lista;
delete listb;

But it breaks on my equivalent of delete lista; at run time. Hopefully someone out there smarter about pointers can help me out. Thanks in advance!

P.S. I'm running Windows 7/MinGW.


Solution

  • A main problem is that you (apparently, you do not offer complete code) delete an object twice: once when iterating through list A, and once when iterating through list B.

    There are three main solutions:

    • Use a ref-counting smart pointer like std::shared_ptr.
      Recommended. Your statement that you do not want to use a smart pointer seems to be made out of ignorance rather than some silly-manager's requirement.

    • Keep the nodes also in a primary list:
      delete a node only when you know that the only list it's still in, is the primary list.

    • Implement a reference count yourself:
      The easiest is again to use an existing library solution such as boost::intrusive_ptr, but all you have to do is to meticulously maintain a reference count in each node. delete when the reference count goes down to 0.

    A fourth possibility is to use a garbage collector such as the Boehm collector, but then the code needs to be structured to support it. Or at least that's my impression. And it may be difficult to get help with that, since very few C++ programmers use that approach (which indicates that it's not entirely free of problems).