Что делать, если деструктор не вызывается после размещения нового [дубликата]

Я изучаю, как использовать новое размещение в С++, и я нахожу пример, как показано ниже:

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)?


person Yves    schedule 04.12.2019    source источник
comment
Но buf — это всего лишь массив байтов... Компилятор и, в меньшей степени, среда выполнения на самом деле не знают содержимого массива. Как тогда может автоматически вызываться деструктор?   -  person Some programmer dude    schedule 04.12.2019
comment
поэтому именно buf отвечает за управление памятью — да, buf управляет памятью. Но выделение/освобождение памяти и создание/уничтожение объектов в ней — это две совершенно разные и независимые вещи. Кстати, обратите внимание, что buf имеет выравнивание 1, поэтому создание в нем объекта типа Complex может привести к смещению, то есть к неопределенному поведению.   -  person Daniel Langr    schedule 04.12.2019
comment
@DanielsaysreinstateMonica Что такое смещение? Не могли бы вы показать мне некоторые документы или статьи об этом?   -  person Yves    schedule 04.12.2019
comment
@Yves Каждый тип имеет два основных свойства памяти — size и alignment. Узнать их можно с помощью операторов sizeof и alignof. Каждый объект данного типа должен быть выровнен в памяти относительно его выравнивания типа. Выравнивание для типов символов, а также их массивов равно 1. Таким образом, buf можно разместить по любому адресу в памяти, например 0x0C01. Если alignof(Complex) больше 1, что, скорее всего, так и есть, то создание объекта типа Complex в buf может привести к смещению объекта. Подробнее см., например, здесь.   -  person Daniel Langr    schedule 04.12.2019