2016-09-02 3 views
0

Если бы я сделал размещение нового на объектах, которые уже созданы в стеке:Размещение нового перезапись существующих объектов

struct s{ 
s() { std::cout << "C\n";} 
~s() { std::cout << "D\n";} 
}; 

int main() { 
     s s1[3]; 
     for(int i=0; i< 3; ++i) 
       s* newS = new (&s1[i]) s(); 
} 

я получаю:

C 
C 
C 
C 
C 
C 
D 
D 
D 

Таким образом, мы не получаем деструкторы для первых 3-х объектов , это безопасно? Если мы просто переопределяем память для объектов, выделенных в куче/стеке, и что объекты не должны освобождать какие-либо ресурсы в деструкторах, это все еще безопасно?

+0

Я не вижу, как это неправильно, вы создаете 3 объекта на стеке, вы получаете конструкторами для тех 3 - то вы используете размещение нового воссоздавать 3 объекта снова в том же месте, чтобы вы снова получили 3 конструктора, и в конце вы получаете 3 деструктора. Вы ожидаете чего-то другого? –

+1

Вообще говоря, это небезопасно. Вы должны явно уничтожить объекты, которые были созданы до повторного использования базового хранилища. –

+0

Очень опасно - деструкторы, вызываемые для исходных 3 объектов, не для 3, созданных с новым размещением. Это может вызвать удивление. –

ответ

2

wandbox example

Ваш вывод не является неожиданным - placement new не вызывает деструктор любого потенциального объекта, хранящегося в ячейке памяти вы обращаетесь. Вам необходимо указать explictly invoke the destructor любого объекта, который занимает ячейку памяти, которую вы пытаетесь использовать, чтобы использовать место размещения new безопасно.

struct s 
{ 
    s() 
    { 
     std::cout << "C\n"; 
    } 
    ~s() 
    { 
     std::cout << "D\n"; 
    } 
}; 

int main() 
{ 
    // Three 's' instances are constructed here. 
    s s1[3]; 

    // (!) You need to explicitly destroy the existing 
    // instances here. 
    for(int i = 0; i < 3; ++i) 
    { 
     s1[i].~s(); 
    } 

    for(int i = 0; i < 3; ++i) 
    { 
     // Three 's' instances are constructed here. 
     s* newS = new(&s1[i]) s(); 
    } 

    // Three 's' instances are destroyed here. 
} 

Выход:

C 
C 
C 
D 
D 
D 
C 
C 
C 
D 
D 
D 
+0

И называть деструкторов явно - это хорошо? рассмотрите это { Класс foo; foo. ~ Class(); } дважды вызывает деструктор –

+0

@SamerTufail: это не «хорошая или плохая» вещь - это необходимо ** при работе с новым размещением. В вашем примере не используется размещение new, поэтому нет необходимости явно обращаться к деструкторам. –

+0

Я знаю. Точнее говоря, он явно уничтожает объекты, выделенные на стек, и воссоздает их с помощью размещения new. Лучше сначала выделить предопределенный размер в куче и использовать это для создания объектов, которые работают с пулами памяти, а не с помощью этого надуманного способа. –

Смежные вопросы