Будет ли использование удаления с указателем базового класса вызвать утечку памяти?

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

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

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

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

Ответы

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

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