https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92200
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID --- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> --- You create a cycle in the shared_ptr ownership, so the reference count never goes to zero and never destroys the object. a->tfut has a reference to the shared state created by std::async, and that shared state has a reference to a. That means the reference count equals two: auto a = make_shared<A>(); a->start_async(); std::cout << "reference count: " << a.use_count() << '\n'; a->tfut.wait(); std::cout << "reference count: " << a.use_count() << '\n'; a.reset(); This prints: Constructing this 0x7fd710000b30 Start async this 0x7fd710000b30 reference count: 2 reference count: 2 Constructing this 0x7fd710001170 Start thread this 0x7fd710001170 Destroying this 0x7fd710001170 When you do a.reset() the reference count goes to one, and so the object is never destroyed. To break this cycle you need to use get() not wait(), so that the future releases its reference on the shared state: auto a = make_shared<A>(); a->start_async(); std::cout << "reference count: " << a.use_count() << '\n'; a->tfut.get(); std::cout << "reference count: " << a.use_count() << '\n'; a.reset(); Now it prints: Constructing this 0x7fece0000b30 Start async this 0x7fece0000b30 reference count: 2 reference count: 1 Destroying this 0x7fece0000b30 Constructing this 0x7fece0000b30 Start thread this 0x7fece0000b30 Destroying this 0x7fece0000b30 So there is no bug in shared_ptr.