Как создать объект в динамической памяти используя malloc()? Нужно ведь явно вызывать конструктор, как это сделать?
Ответ
Вам нужен placement new.
Например, так:
void* place = malloc(sizeof(Object));
Object* o = new(place) Object();
Не забудьте в конце вызвать и деструктор вручную:
o->~Object();
и если нужно
free(place);
Документация:
https://isocpp.org/wiki/faq/dtors#placement-new
Для случая, когда у вас память выделена заранее, вам придётся позаботиться о выравнивании. Обычный указатель, который возвращает malloc, имеет выравнивание, достаточное для нормально объявленного класса, то есть, класса, определение которого не содержит alignas() (а также определение классов его полей), и значит, ничего больше делать не нужно.
Если это (отсутствие alignas) не гарантировано, у вас есть два пути. Вы можете вместо malloc использовать aligned_alloc (или _aligned_malloc на старых версиях Visual Studio), который выдаёт malloc с нужным выравниванием:
void* place = std::aligned_alloc(alignof(Object), sizeof(Object));
void* place = _aligned_malloc(sizeof(Object), alignof(Object));
(да, порядок противоположный).
Или если вам нужен именно malloc, то можно заказать больше памяти для того, чтобы было место для выравнивания, и выровнять указатель при помощи std::align
std::size_t alloc_size = sizeof(Object) + alignof(Object) - 1;
void* place = malloc(alloc_size);
void* aligned_place = place;
if (std::align(alignof(Object), sizeof(Object), aligned_place, alloc_size))
{
Object* o = new(aligned_place) Object();
// ...
}
Эта вторая техника пригодится, если вы захотите выделить в одном буфере несколько объектов.
Комментариев нет:
Отправить комментарий