https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118854
--- Comment #15 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Nicholas Williams from comment #13) > (In reply to Jonathan Wakely from comment #10) > > If you need to make copies of a shared_ptr while also modifying it, you need > > to use std::atomic<std::shared_ptr<T>> (or > > std::experimental::atomic_shared_ptr). > > Using std::atomic<std::shared_ptr> results in the same race condition > heap-use-after-free while copying the shared_ptr: Probably because you're still destroying it while it's still in use. Atomics allow concurrent reads and writes, but you still can't access an object during or after its destructor starts executing. > (In reply to Jonathan Wakely from comment #12) > > ***any of those accesses uses a non-const member function of shared_ptr then > > a data race will occur*** > > shared_ptr::shared_ptr( shared_ptr const & other ); > > By definition, uses of `other` should exclusively use only const members, > not non-const members, of `other`, because `other` is declared `const`. Just because the copy constructor takes a const-reference to pInstance and copies it, doesn't mean that the object is immutable and cannot possibly be modified in the other thread. It just means the copy constructor can't modify it. The problem is not that the copy constructor modifies 'other', the problem is that it's being modified concurrently in another thread. Because its destructor is running in the main thread, and you're making a copy of it in the background thread. You can't copy something while it's being destroyed.