可能重复:
Does std::list::remove method call destructor of each removed element?
我有一个Parent类,并将两个子类Foo和Bar子类化。类声明看起来像这样:
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看起来和Foo差不多。我不认为他们的行动功能和他们的私人成员的差异会产生很大的不同(它也是一堆整体)。
我需要列出一个充满Foos和Bars的父母列表。我这样做是为了添加它们并随后删除它们:
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库进行这项任务)
答案 0 :(得分:3)
您的列表包含指向对象的指针。您只是删除指针但不释放它指向的内存(销毁对象)。在删除之前,您需要在指针上调用delete
。这意味着list::remove_if
无法在此处完成工作。您需要遍历列表,删除符合条件的每个对象,并使用迭代器调用list::erase
。
这里没有简单的方法。您需要运行时多态,因此您需要指针而不能使用boost::shared_ptr
。也许你可以欺骗并使用std::shared_ptr
或std::unique_ptr
;)