Будет ли использование удаления с указателем базового класса вызвать утечку памяти?
Учитывая, что два класса имеют только примитивный тип данных и не имеют специального деструктора/деаллокатора.
Предоставляет ли спецификация С++ его освобождение с правильным размером?
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" определяет деструктор или содержит какие-либо элементы с нетривиальным деструктором, они не будут вызваны, что вызовет утечку потенциальной памяти. Однако это не относится к вашему образцу кода.