Указатель члена, определенный с 'новым' в заголовочном файле, утечка памяти? - PullRequest
0 голосов
/ 20 февраля 2019

В коде, который я использую, я нашел объявление класса в заголовочном файле, который содержит указатель на const в качестве члена, который определен как «новый» прямо в заголовочном файле.

Соответствующий «удалить»находится в деструкторе (также определенном прямо в заголовке).

Это использование нормально?Это создает утечку памяти?Деструктор вызывается только тогда, когда объект этого класса уничтожается либо удалением (при создании с новым), либо выходом из области видимости (при создании в стеке).Но «new» находится не в конструкторе, а в объявлении класса.Разве это не выполнено раньше?Может быть, даже когда заголовок анализируется?Это гарантировано для меня совпадает с удалением в деструкторе?

class Foo {
public:
  explicit Foo(){}
  ~Foo() {
    delete this->bar;
  }

private:
  const Baz* bar = new Baz();
}; 

1 Ответ

0 голосов
/ 20 февраля 2019

Создает ли утечка памяти?

Потенциально, да.Если вы присваиваете экземпляру Foo, память, принадлежащая предыдущему значению указателя, просачивается.

Разве это не выполнялось раньше?Может быть, даже когда заголовок анализируется?

Нет.Члены инициализируются конструктором.Инициализатор члена по умолчанию в объявлении члена используется, если конструктор не указывает явно инициализатор члена (например, в случае с объявленным вами конструктором).

Это использование нормально?Это гарантированно для меня совпадает с удалением в деструкторе?

Нет.Помимо утечки, если вы сделаете копию объекта, будет два удаления, соответствующих только одному новому.Программа будет иметь неопределенное поведение.

Самое простое решение как для утечки, так и для UB - использовать std::unique_ptr вместо простого указателя.(Или, возможно, std::shared_ptr в случае, если вы хотите, чтобы класс был копируемым, и хотите, чтобы копии разделяли владение одним и тем же Baz объектом).

Хотя с инициализатором члена по умолчанию проблем нет.Упомянутые выше проблемы связаны с отсутствием инвариантов классов, которые необходимы при работе с ресурсами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...