Объект все еще доступен после того, как std :: unique_ptr выходит из области видимости. Различное поведение во время выполнения

Следующий код переходит к функции modify_entry указатель на объект типа Entry и внутри тела функции а unique_ptr принимает необработанный указатель. Однако объект, на который указывают указатели, кажется, продолжает жить после возврата из функции.

Когда я компилирую этот код

#include <iostream>
#include <memory>

struct Entry {

Entry(std::string name) : name_(name) { std::cout << "Constructor for " + name_ + '\n'; }
~Entry() { std::cout << "Destructor for " + name_ + '\n'; }
std::string name_;

};

void modify_entry(Entry* e_ptr){

std::cout << "Inside modify_entry()\n";
std::unique_ptr<Entry>{e_ptr}->name_ += " Doe";

}

int main(int argc, const char * argv[])
{

Entry* entry_ptr = new Entry("John");
modify_entry(entry_ptr);
std::cout << "Back from modify_entry()\n";
std::cout << entry_ptr->name_ << '\n';      // <---- line 25

return 0;

}

с

Clang версия 3.4 (теги / RELEASE_34 / финал)

Цель: x86_64-apple-darwin13.1.0

Модель потока: posix

Он работает без ошибок и вывод

Конструктор для Джона

Внутри modify_entry ()

Разрушитель для Джона Доу

Вернуться из modify_entry ()

Джон Доу

Вот, однако, я получаю ошибку во время выполнения из-за строки 25.

Q: Почему нет ошибки времени выполнения, когда я запускаю исполняемый файл, сгенерированный clang?

Буду очень признателен, если кто-то сможет прояснить ситуацию. Обратите внимание, что я не пытаюсь правильно передать право собственности. это надуманный пример плохого кода является побочным продуктом процесса отладки. make_unique и переместить семантику для unique_ptr и т. д. отлично, но это не то, что я спрашиваю.

Заранее спасибо.

1

Решение

Однако объект, на который указывают указатели, кажется, продолжает жить после возврата из функции.

Ключевым моментом здесь является «кажется». На самом деле, EntryСрок жизни заканчивается в конце этой строки:

 std::unique_ptr<Entry>{e_ptr}->name_ += " Doe";

unique_ptr завладела памятью, но временная unique_ptrвремя жизни заканчивается в конце этого оператора, поэтому он также удаляет Entry что он владеет. Доступ к памяти, которая ранее использовалась объектом, является неопределенным поведением. То, что он работает на некоторых платформах, а не на других, это просто природа неопределенного поведения.

6

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

В: Почему при запуске исполняемого файла, созданного clang, не возникает ошибка времени выполнения?

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

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

6

Потому что ты делаешь это неопределенное поведение, когда в main Функция, которую вы используете указатель на разрушенный объект.

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

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