0

Possible Duplicate:
Does std::list::remove method call destructor of each removed element?

I have a Parent class and subclassed the two children Foo and Bar. Class declarations look something like this:

class Parent {
    public:
        virtual void action()=0;
        std::string getName() {return name;}
        Parent(std::string name): name(name) {}
        virtual ~Parent() {}
    private:
        std::string name;
}
class Foo {
    public:
        virtual void action(); //Declared somewhere else.
        Foo(int a, int b, unsigned long c, std::string name): Parent(name),a(a),b(b),c(c) {}
        virtual ~Foo() {}
    private:
        int a,b;
        unsigned long c;
}

Bar looks pretty much the same as Foo. I don't think the differences in their action functions and their private members will make much of a difference (it's also a bunch of ints).

I need to make a list of Parents filled with Foos and Bars. I do this to add them in and subsequently remove them:

std::list<Parent *> pList;
pList.push_back(new Foo(1,2,3,"Thing"));
removeFromList(&pList, "Thing");

Where removeFromList is defined as follows:

// Binary predicate struct, find objects with matching name.
struct NameMatch : public std::binary_function< Parent*, std::string, bool > {
     bool operator () (Parent* p, const std::string name) const {
         return (p->getName()==name);
     }
};

/* Removes a named object from the list of Foos. 
   Does nothing if a matching name can't be found. */
void removeFromList(std::list<Parent *> *pList, std::string name) {
    pList->remove_if(std::bind2nd(NameMatch(),name));
}

However, once I exit the program after, Valgrind will report there are memory leaks, where the lines referenced by main.cpp are the push_back operations done on the list:

==14230== 949 (520 direct, 429 indirect) bytes in 13 blocks are definitely lost in loss record 52 of 61
==14230==    at 0x4C28B35: operator new(unsigned long) (vg_replace_malloc.c:261)
==14230==    by 0x4026C8: main (main.cpp:93)
==14230== 
==14230== 5,970 (960 direct, 5,010 indirect) bytes in 30 blocks are definitely lost in loss record 60 of 61
==14230==    at 0x4C28B35: operator new(unsigned long) (vg_replace_malloc.c:261)
==14230==    by 0x40296A: main (main.cpp:112)

Does this mean that the list's remove_if function doesn't deallocate memory, or is there an error I made somewhere else? And how would I make sure that my program won't leak memory from using these classes? A second set of eyes would be really helpful.

Thanks in advance! (Oh, just an FYI, I can't use the Boost libraries for this assignment)

Community
  • 1
  • 1
SpeedBurner
  • 711
  • 2
  • 9
  • 18

1 Answers1

3

Your list contain pointers to objects. You are only removing the pointer but not deallocating the memory it points to (destroying the object). You need to call delete on the pointer before removing it. This means that a list::remove_if cannot do the job here. You need to traverse the list, delete each object that matches the criteria and call list::erase with the iterator.

There is no easy way out here. You need runtime-polymorphism, so you need pointers and you cannot use boost::shared_ptr. Maybe you can cheat and use std::shared_ptr or std::unique_ptr ;)

pmr
  • 58,701
  • 10
  • 113
  • 156
  • "make sure that my program won't leak memory": Always use containers of smart pointers instead of containers of plain pointers. – ysdx Jan 17 '12 at 00:06
  • @ysdx Now he just needs the smart pointers. Sounds like that assignment just got a lot harder. – pmr Jan 17 '12 at 00:08