C++ destructor memory leak

2019-07-13 19:31发布

问题:

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!

回答1:

You've got to make sure that your destructor is virtual so that the proper derived destructor is called.

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


回答2:

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.



回答3:

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.