Почему этот код НЕ генерирует двойное освобождение, когда общие указатели выходят из области видимости?
int main()
{
{
auto * ptr = new int(1);
shared_ptr<int> a( ptr );
shared_ptr<int> b( ptr );
cout << "ok: " << *a << *b << endl;
}
cout << "still ok" << endl;
return 0;
}
Почему этот код НЕ генерирует двойное освобождение, когда общие указатели
выйти за рамки?
Почему вы думаете, что нет?
Это неопределенное поведение, все может случиться. Это включает в себя распечатку вашей программы still ok
,
Этот код UB, так что-нибудь может случиться.
За a
удалять вызывается по уже удаленному указателю.
Создание более одного общего указателя из необработанного указателя приводит к неопределенное поведение так как:
указанный объект будет иметь несколько блоков управления.
Отрывок из «Эффективного современного C ++», стр. 129, ст. 19
Избегайте передачи сырых указателей на std::shared_ptr
конструктор. Если вы действительно должны использовать необработанные указатели, тогда используйте результат оператора new
вместо указателя:
std::shared_ptr<int> a(new int(1));
или используйте станд :: make_shared макрос:
std::shared_ptr<int> a = std::make_shared<int>(1);
и создайте второй общий указатель, передав a
в качестве аргумента для конструктора:
std::shared_ptr<int> b(a);