C++析构函数内存泄漏

3

关于正确处理析构函数的相对简单的问题...

首先,我有一个类,大致如下:

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

如果我将类型为Baz的对象添加到Foo中,然后尝试ReleaseObjects(),则会出现内存泄漏(通过valgrind)。问题指向baz泄漏,我猜这意味着bar中的析构函数从未被调用?所以我想知道的是如何在尝试销毁该对象时调用Bar析构函数(我无法更改Bar类,但我可以更改Foo)。
编辑: 哎呀,对于语法错误我表示抱歉。无论如何,感谢所有回复,愚笨的我忘记在我的Baz类中实现正确的析构函数!哦,Baz实际上是一个模板类,但我觉得Baz与我的问题有点不相关,问题实际上在于Bar中的析构函数没有被调用...好的,再次感谢,我认为我已经从这里解决了问题!

6
析构函数在Object类中是否是虚函数?请附上Object类的代码。 - Tom
5
这段代码没有泄露。甚至这段代码都没有编译通过。请发布实际的代码。 - Benjamin Lindley
1
你能发布关于Baz的类(或者其他东西)吗? - MGZero
1
请提交一个最小化、完整的程序,以演示错误。有关更多信息,请参阅http://sscce.org。 - Robᵩ
1
使用RAII! - sbi
显示剩余3条评论
3个回答

6

你必须确保你的析构函数是虚函数,这样才能调用到正确的派生类析构函数。

class Object {
 . . .
 virtual ~Object()
 . . .
};

这基本上就是我忘记实现的!我还以为我的问题完全不同...谢谢! - Fault

2
我不完全了解你的情况,但是由于你使用了公共继承,你可能需要虚析构函数。特别地,基类(Object)需要一个虚析构函数。
请注意,你提供的代码无法编译。new操作符返回指针,所以baz必须是一个指针。

0

你应该总是使用智能指针。这些类型的行为类似于指针,但会自动释放内存,避免了任何此类函数的需要。它们避免了各种令人讨厌的错误——如果你使用了一个 shared_ptr<Bar> 并将其向下转换,可能包括这个错误。

如果你想在C++中编写非平凡的软件,你必须知道和理解智能指针。


如果问题是一个非虚析构函数,我认为 shared_ptr 不会起作用。(不过我不是100%确定) - Mooing Duck
@MooingDuck:它在析构函数中使用类型擦除,因此如果您从“Bar”开始,则避免此问题。 - Puppy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接