Правильное использование нового и явного вызова деструктора для размещения

В недавнем интервью меня попросили ответить, безопасен ли этот код и будет ли когда-нибудь использовать что-то вроде этого:

template<class T> T *CTricky<T>::Safe_Or_Not (T *object)
{

object->T::~T ();

::new (object) T;

return object;

}

Мой ответ был: этот код безопасен, и я бы использовал эту технику, если бы мне нужно было освободить ресурсы, используемые моим «объектом», вызвав его деструктор, но в то же время я не хотел освобождать свой «объект» и хотел это держать его место в памяти (достигается путем размещения нового здесь).

Честно говоря, я не ищу помощи, чтобы правильно ответить на этот вопрос на собеседовании. Мне только любопытно узнать, правильное ли мое понимание размещения новых и явных вызовов деструкторов.

0

Решение

это НЕ безопасный:
Следующее может привести к утечке памяти 🙁https://ideone.com/70YqhM)

Base* b = new Derived;
b = Safe_Or_Not(b);

Производный деструктор никогда не называется.

И как другое упоминание:

  • Нет нулевой проверки.
  • Исключение безопасности не учитывается
1

Другие решения

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

Хотя есть несколько других вещей, на которые нужно обратить внимание (например, нулевой указатель), это, пожалуй, наименее очевидный и наиболее трудный, чтобы он не вызывал проблем (в основном, ваш единственный выбор — мириться с неопределенным поведением и надейтесь на лучшее или поймайте исключение и выйдите из программы до того, как раскрутка стека может произойти).

2

Я думаю, что общая логика «явный вызов деструктора + размещение нового» безопасна.
Однако этот код не является безопасным, потому что:
— Вы не проверяете, является ли указатель нулевым.
— исключительная безопасность не учитывается

1
По вопросам рекламы [email protected]