Утечка памяти в деструкторе C ++ - PullRequest
2 голосов
/ 18 октября 2011

Относительно простой вопрос о правильной обработке деструкторов ...

Сначала у меня есть класс, похожий на этот:

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'. Проблема класса объекта:

class Bar : public Object {
public:
    Bar() {
        baz = new Baz();
    }

    ~Bar() { delete baz; }
private:
    Baz* baz;
}

Если я добавлю объект типа Baz в Foo, а затем попробую ReleaseObjects (), я получу утечку памяти (valgrind). Проблема указывает на утечку базы, и я думаю, это означает, что деструктор в баре никогда не вызывается? Поэтому я хотел бы знать, как вызывать деструктор Bar при попытке уничтожить этот объект (я не могу изменить класс Bar, но я могу изменить Foo).

Edit: Ой, извините за синтаксические ошибки. В любом случае, спасибо за все ответы, глупо, я забыл реализовать правильный деструктор в моем классе Baz! Да, и Baz на самом деле является шаблоном класса, но я подумал, что Baz был как бы неуместен в моем вопросе, и проблема была в том, что деструктора в Bar не вызывали ... ну, я был не прав, проблема в Baz в конце концов. Но еще раз спасибо, я думаю, что я понял это отсюда!

Ответы [ 3 ]

6 голосов
/ 18 октября 2011

Вы должны убедиться, что ваш деструктор является виртуальным, чтобы вызывался правильный производный деструктор.

class Object {
 . . .
 virtual ~Object()
 . . .
};
2 голосов
/ 18 октября 2011

Я не совсем понимаю ваш сценарий, но , поскольку у вас есть публичное наследование, вам, вероятно, нужны виртуальные деструкторы .В частности, базовый класс (Object) нуждается в виртуальном деструкторе.

Обратите внимание, что данный код не может компилироваться.Оператор new возвращает указатель, поэтому baz должен быть указателем.

0 голосов
/ 18 октября 2011

Вы всегда должны всегда использовать умные указатели.Эти типы ведут себя как указатели, но автоматически освобождают память и исключают необходимость каких-либо таких функций.Они избегают всевозможных неприятных ошибок - потенциально включая эту, если вы использовали shared_ptr<Bar> и преобразили его.

Если вы хотите написать нетривиальное программное обеспечение на C ++, вы должны знать и понимать умные указатели.

...