2012-01-17 3 views
0

Можно создать дубликат:
Does std::list::remove method call destructor of each removed element?C++ - std :: list remove_if не освобождает память?

У меня есть класс Parent и подклассы двух детей Foo и бар. Декларации классов выглядят примерно так:

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; 
} 

Бар выглядит примерно так же, как Foo. Я не думаю, что различия в их функциях действий и их частных членах будут иметь большое значение (это также куча ints).

Мне нужно составить список родителей, заполненных футами и барами. Я делаю это, чтобы добавить их и затем удалить их:

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

Где removeFromList определяется следующим образом:

// 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)); 
} 

Однако, как только я выйти из программы после того, как, Valgrind сообщит есть утечки памяти, где линия, на которые ссылаются main.cpp являются операциями push_back, сделанных в списке:

==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) 

Означает ли это, что remove_if функция Листа не освобождает память, или есть ошибка, которую я сделал где-то еще? И как бы я удостоверился, что моя программа не будет утечка памяти из использования этих классов? Второй набор глаз был бы действительно полезен.

Заранее благодарен! (О, просто FYI, я не могу использовать библиотеки Boost для этого назначения)

ответ

3

Ваш список содержит указатели на объекты. Вы удаляете указатель, но не освобождаете память, на которую указывает (уничтожая объект). Перед его удалением необходимо вызвать delete. Это означает, что list::remove_if не может выполнять эту работу здесь. Вам нужно пройти по списку, удалить каждый объект, соответствующий критериям, и вызвать list::erase с помощью итератора.

Здесь нет простого выхода. Вам нужен runtime-полиморфизм, поэтому вам нужны указатели, и вы не можете использовать boost::shared_ptr. Может быть, вы можете обмануть и использовать std::shared_ptr или;

+0

«убедитесь, что моя программа не просачивается»: всегда используйте контейнеры интеллектуальных указателей вместо контейнеров с обычными указателями. – ysdx

+0

@ysdx Теперь ему нужны только умные указатели. Похоже, что это задание стало намного сложнее. – pmr

+0

Ху мальчик. Спасибо вам за помощь! – SpeedBurner

Смежные вопросы