C ++析构函数内存泄漏

时间:2011-10-18 17:43:26

标签: c++ memory-leaks destructor delete-operator

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

首先,我有一个类似这样的课程:

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中。但再次感谢,我想我从这里弄明白了!

3 个答案:

答案 0 :(得分:6)

您必须确保析构函数是虚拟的,以便调用正确的派生析构函数。

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

答案 1 :(得分:2)

我不完全了解您的情况,但since you've got public inheritance, you probably want virtual destructors。特别是,基类(Object)需要一个虚拟析构函数。

请注意,您的代码无法编译。新运算符返回一个指针,因此baz必须是一个指针。

答案 2 :(得分:0)

您应该始终使用智能指针。这些类型的行为类似于指针,但会自动释放内存,并且无需任何此类函数。他们避免了各种令人讨厌的错误 - 可能包括这个错误,如果你使用了shared_ptr<Bar>并将其降级了。

如果您想用C ++编写非平凡的软件,必须知道并理解智能指针。