C++析构函数内存泄漏
关于正确处理析构函数的相对简单的问题...
首先,我有一个类似这样的类:
class Foo {
public:
ReleaseObjects() {
for (std::map<size_t, Object*>::iterator iter = objects.begin(); iter != objects.end(); iter++) {
delete (*iter).second;
}
objects.clear();
}
private:
std::map<size_t,Object*> objects;
}
因此该函数只是删除使用“new”创建的对象。问题是一个 Object 类:
class Bar : public Object {
public:
Bar() {
baz = new Baz();
}
~Bar() { delete baz; }
private:
Baz* baz;
}
如果我向 Foo 添加类型 Baz 对象,然后尝试 ReleaseObjects(),则会出现内存泄漏 (valgrind)。问题表明 baz 被泄露,我猜这意味着 bar 中的析构函数从未被调用?所以我想知道的是在尝试销毁该对象时如何调用 Bar 析构函数(我无法更改 Bar 类,但我可以更改 Foo)。
编辑: 糟糕,抱歉出现语法错误。不管怎样,感谢所有的回复,愚蠢的我忘记在我的 Baz 类中实现一个正确的析构函数!哦,Baz 实际上是一个模板类,但我认为 Baz 与我的问题有点无关,问题是 Bar 中的析构函数没有被调用......好吧,我错了,问题毕竟在 Baz 中。但再次感谢,我想我从这里弄清楚了!
Relatively simple question about handling destructors properly...
First I've got a class that's something like this:
class Foo {
public:
ReleaseObjects() {
for (std::map<size_t, Object*>::iterator iter = objects.begin(); iter != objects.end(); iter++) {
delete (*iter).second;
}
objects.clear();
}
private:
std::map<size_t,Object*> objects;
}
So the function simply deletes the objects, which were created using 'new'. Problem is an Object class:
class Bar : public Object {
public:
Bar() {
baz = new Baz();
}
~Bar() { delete baz; }
private:
Baz* baz;
}
If I add a type Baz object to Foo, and then try to ReleaseObjects(), I get a memory leak (valgrind). The issue points to baz being leaked, and I guess that means the destructor in bar is never called? So what I'd like to know is how to call the Bar destructor when trying to destroy that object (I can't alter the Bar class, but I can alter Foo).
Edit:
Oops, sorry for the syntax errors. Anyways, thanks for all the replies, silly me forgot to implement a proper destructor in my Baz class! Oh, and Baz is actually a template class, but I figured Baz was sort of irrelevant to my question, and that the problem was the destructor in Bar not being called... well, I was wrong, problem is in Baz after all. But thanks again, I think I got it figured out from here!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您必须确保您的析构函数是虚拟的,以便调用正确的派生析构函数。
You've got to make sure that your destructor is virtual so that the proper derived destructor is called.
我不完全理解你的情况,但是因为你'已经有了公共继承,您可能需要虚拟析构函数。特别是,基类(Object)需要一个虚拟析构函数。
请注意,您给定的代码无法编译。 new 运算符返回一个指针,因此 baz 必须是一个指针。
I don't fully understand your scenario, but since you've got public inheritance, you probably want virtual destructors. In particular, the base class (Object) needs a virtual destructor.
Note that your given code cannot compile. The new operator returns a pointer, so
baz
must be a pointer.您应该始终使用智能指针。这些类型的行为类似于指针,但会自动释放内存,并且不需要任何此类函数。它们避免了各种令人讨厌的错误 - 如果您使用
shared_ptr
并将其向下转换,则可能包括这个错误。如果您想用 C++ 编写重要的软件,您必须了解并理解智能指针。
You should always always use smart pointers. These types behave like pointers but release memory automatically, and void the need for any such functions. They avoid all sorts of nasty bugs- potentially including this one, if you used a
shared_ptr<Bar>
and casted it down.If you want to write non-trivial software in C++, you must know and understand smart pointers.