Подтвердить что ты не робот

Разве unique_ptr:: release() вызывает деструктор?

Правильно ли этот код?

auto v =  make_unique<int>(12);
v.release();     // is this possible?

Является ли он эквивалентным delete исходного указателя?

4b9b3361

Ответ 1

Нет, код вызывает утечку памяти. release используется для освобождения права собственности на управляемый объект без его удаления:

auto v = make_unique<int>(12);  // manages the object
int * raw = v.release();        // pointer to no-longer-managed object
delete raw;                     // needs manual deletion

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

Чтобы удалить объект, используйте reset.

auto v = make_unique<int>(12);  // manages the object
v.reset();                      // delete the object, leaving v empty

Ответ 2

Правильно ли этот код?

Нет. Используйте std::unique_ptr<>::reset() для удаления внутреннего необработанного указателя:

auto v =  std::make_unique<int>(12);
v.reset(); // deletes the raw pointer

После этого std::unique_ptr<>::get() вернет nullptr (если вы не указали параметр nullptr std::unique_ptr<>::reset()).

Ответ 3

Правильно ли этот код?

Нет! Произойдет утечка.

release() просто позвоните вызывающему коду повторно захватить память, хранящуюся в unique_ptr, пока она не будет вызвана. Если вы не назначили указатель, возвращаемый release(), у вас будет только утечка.

Явное удаление для unique_ptr будет reset(). Но помните, что unique_ptr существует, так что вам не нужно напрямую управлять памятью, которую они хранят. То есть вы должны знать, что unique_ptr безопасно удалит свой основной необработанный указатель, как только он выйдет из области видимости.

Поэтому у вас должна быть очень веская причина для ручного управления памятью в автоматическом объекте управления памятью.

Ответ 4

release будет просачивать ваш необработанный указатель, так как вы его не присваиваете.

Он предназначен для использования для чего-то вроде

int* x = v.release();

Это означает, что v больше не управляет временем жизни этого указателя, он делегирует собственность raw pointer на x. Если вы просто release не присваиваете ничего, вы пропустите исходный указатель.

Ответ 5

для произвольных типов может быть немного сложно:

  unique_ptr<Foo> v = get_me_some_foo();  // manages the object
  Foo * raw = v.release();        // pointer to no-longer-managed object
  delete raw;

почти правильно.

  unique_ptr<Foo> v = get_me_some_foo();  // manages the object
  Foo * ptr = v.release();        // pointer to no-longer-managed object
  v.get_deleter() ( ptr );

этот был бы правильным во всех ситуациях; может быть пользовательский делетер, определенный по типу Foo, но использование делетера, возвращаемого объектом unique_ptr, хорошо для всех случаев.