Давайте перейдем к следующему пункту
- , почему происходит сбой моего приложения, если я не использую новый?
Виртуальная таблица повреждена.
Виртуальная таблица застревает сразу после выделенной памяти.когда вы new
класс, сгенерированный код будет правильно настроить vtable.Однако malloc не будет правильно инициализировать vtable
Чтобы увидеть виртуальную таблицу, запустите g ++ -fdump-class -ierarchy
Vtable for Derived
Derived::_ZTV7Derived: 3u entries
0 (int (*)(...))0
8 (int (*)(...))(& _ZTI7Derived)
16 Derived::x
Class Derived
size=16 align=8
base size=12 base align=8
Derived (0x10209fc40) 0
vptr=((& Derived::_ZTV7Derived) + 16u) <-- notice how this is part of the structure
Base (0x10209fcb0) 0 nearly-empty
primary-for Derived (0x10209fc40)
По аналогичной причине, без перегрузки оператора =, сгенерированныйассемблерный код будет копировать только данные, а не vtable [опять же, компилятор знает, как копировать данные, а не vtable]
Если вы хотите увидеть версию на основе указателя с допустимой функцией vtable:
Derived e(123);
d = &e;
- Нужно ли использовать new также для неполиморфных типов?
Если вы используете виртуальные функции, то да, даже для неполиморфных типов
- Я надеюсь, что выравнивание, необходимое для моего класса, - это размер класса, возвращаемый sizeof, так что любой адрес в форме address_returned_by_malloc + i * sizeof (my_class) подходит для размещения моих объектов.
Выравнивание не является проблемой.