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

17

Учитывая, что два класса имеют только примитивный тип данных и не имеют специального деструктора / деаллокатора. Предоставляет ли спецификация 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 ++.

    
задан kcwu 20.01.2010 в 11:32
источник

5 ответов

23

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

  

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

    
ответ дан James Hopkin 20.01.2010 в 11:39
источник
16

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

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

    
ответ дан anon 20.01.2010 в 11:35
источник
1

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

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

    
ответ дан sharptooth 20.01.2010 в 11:37
источник
1

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

    
ответ дан psychotik 20.01.2010 в 11:38
источник
0

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

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

    
ответ дан Alexander Gessler 20.01.2010 в 11:36
источник