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.

Reply via email to