Будет ли использование delete с указателем на базовый класс причиной утечки памяти? - PullRequest
18 голосов
/ 20 января 2010

Данные два класса имеют только примитивный тип данных и не имеют собственного деструктора / деллокатора.Гарантирует ли спецификация C ++, что он освободит правильный размер?

struct A { int foo; };
struct B: public A { int bar[100000]; };
A *a = (A*)new B;
delete a;

Я хочу знать, нужно ли мне писать пустой virtual dtor?

Я пробовал g ++ и vc ++2008, и они не вызовут утечку.Но я хотел бы знать, что правильно в стандарте C ++.

Ответы [ 5 ]

24 голосов
/ 20 января 2010

Если деструктор базового класса не является виртуальным, это неопределенное поведение. См. 5.3.5 / 4:

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

16 голосов
/ 20 января 2010

Согласно стандарту C ++, у вас есть неопределенное поведение - это может проявиться как утечка, а может и нет. Чтобы ваш код был корректным, вам нужен виртуальный деструктор.

Кроме того, вам не нужно это (A *) приведение. Всякий раз, когда вы обнаруживаете, что используете приведение в стиле C в C ++, вы можете быть совершенно уверены, что это либо не нужно, либо ваш код неверен.

1 голос
/ 20 января 2010

Только для примитивных данных, я думаю, у вас все хорошо. Вы можете на законных основаниях не хотеть нести стоимость V-таблицы в этом случае. В противном случае, виртуальный d'tor определенно предпочтительнее.

1 голос
/ 20 января 2010

Это неопределенное поведение - может быть, все в порядке, может быть, все идет не так. Либо не делайте этого, либо снабжайте базовый класс виртуальным деструктором.

В большинстве реализаций это не протекает - в классе нет выделенных в куче функций-членов, поэтому единственное, что нужно сделать, когда delete, это освободить память. Выделение памяти использует только адрес объекта, ничего более, куча делает все остальное.

0 голосов
/ 20 января 2010

Он будет освобожден с правильным размером, потому что размер, который должен быть освобожден, является свойством области динамической памяти, которую вы получили (размер не передается free() -подобным функциям!).

Тем не менее, d'tor не называется. Если «B» определяет деструктор или содержит какие-либо элементы с нетривиальным деструктором, они не будут вызваны, что приведет к потенциальной утечке памяти. Однако в вашем примере кода это не так.

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