Home > OS >  Thread-safety of reference count in std::shared_ptr
Thread-safety of reference count in std::shared_ptr

Time:06-13

Looking at this implementation of std::shared_ptr enter image description here

CodePudding user response:

Question 1:

The implementation linked to is not thread-safe at all. You are correct that the shared reference counter should be atomic, not pointers to it. std::atomic<int*> here makes no sense.

Note that just changing std::atomic<int*> to std::atomic<int>* won't be enough to fix this either. For example the destructor is decrementing the reference count and checking it against 0 non-atomically. So another thread could get in between these two operations and then they will both think that they should delete the object causing undefined behavior.

As mentioned by @fabian in the comments, it is also far from a correct non-thread-safe shared pointer implementation. For example with the test case

{
    Shared_ptr<int> a(new int);
    Shared_ptr<int> b(new int);
    b = a;
}

it will leak the second allocation. So it doesn't even do the basics correctly.

Even more, in the simple test case

{
    Shared_ptr<int> a(new int);
}

it leaks the allocated memory for the reference counter (which it always leaks).


Question 2:

There is no reason to have a null pointer check there except to avoid printing the message. In fact, if we want to adhere to the standard's specification of std::default_delete for default_deleter, then at best it is wrong to check for nullptr, since that is specified to call delete unconditionally.

But the only possible edge case where this could matter is if a custom operator delete would be called that causes some side effect for a null pointer argument. However, it is anyway unspecified whether delete will call operator delete if passed a null pointer, so that's not practically relevant either.

  • Related