Я изучаю, как использовать новое размещение в С++, и я нахожу пример, как показано ниже:
int main()
{
// buffer on stack
unsigned char buf[100];
// using placement new
Complex *pe = new (buf) Complex(2.6, 3.9);
pe->print();
// No delete : Explicit call to Destructor.
pe->~Complex();
return 0;
}
Я понимаю, что делает этот фрагмент кода, но у меня есть вопрос:
Можно ли удалить pe->~Complex()
?
Насколько я понимаю, объект pe
расположен на buf
, поэтому именно buf
отвечает за управление памятью. Я имею в виду, что вызывать деструктор pe
не обязательно. Я прав?
Если в классе Complex
есть new object
, очевидно, мы должны delete
его в деструкторе. Вот мой вопрос: должен ли new object
в Complex
располагаться на buf
? Или он может располагаться в любой памяти стека (как и обычный new
)?
buf
— это всего лишь массив байтов... Компилятор и, в меньшей степени, среда выполнения на самом деле не знают содержимого массива. Как тогда может автоматически вызываться деструктор? - person Some programmer dude   schedule 04.12.2019buf
отвечает за управление памятью — да,buf
управляет памятью. Но выделение/освобождение памяти и создание/уничтожение объектов в ней — это две совершенно разные и независимые вещи. Кстати, обратите внимание, чтоbuf
имеет выравнивание 1, поэтому создание в нем объекта типаComplex
может привести к смещению, то есть к неопределенному поведению. - person Daniel Langr   schedule 04.12.2019sizeof
иalignof
. Каждый объект данного типа должен быть выровнен в памяти относительно его выравнивания типа. Выравнивание для типов символов, а также их массивов равно 1. Таким образом,buf
можно разместить по любому адресу в памяти, например 0x0C01. Еслиalignof(Complex)
больше 1, что, скорее всего, так и есть, то создание объекта типаComplex
вbuf
может привести к смещению объекта. Подробнее см., например, здесь. - person Daniel Langr   schedule 04.12.2019