2

I have a double free bug using std::shared_ptr and trying to get know why. I am using shared_ptr in multithread environment , one thread sometimes replaces some element in a global array

std::shared_ptr<Bucket>  globalTable[100]; // global elements storage

using:

globalTable[idx].reset(newBucket);

and the other thread reads this table sometimes using :

std::shared_ptr<Bucket> bkt(globalTable[pIdx]);
// do calculations with bkt-> items

After this I am receiving double-free error, and AddressSanitizer says that the second code tries to free an object that was destroyed by the first one . How it is possible ? As I know shared_ptr must be completly thread safe.

2 Answers 2

3

Not all operations on a std::shared_ptr are thread-safe.

Specifically, the reference-counts are managed atomically, but it's your responsibility to make sure the std::shared_ptr instance you access is not concurrently modified.

You fail that responsibility, resulting in a data-race and the expected undefined behavior, manifesting as a double-free in your case.

Sign up to request clarification or add additional context in comments.

2 Comments

actually my inner object is constant and even this gist.github.com/martende/c71535dd5f510d80bcf2934c8734d1cc concurrent access pattern produces double-free . Is there exists a way to write this code on shared_ptr ?
gist.github.com/martende/d17ccf744f6b3db9f10101a5935251bb - wrapping with mutexes is working ofcourse
2

Reset does not guarantee you thread saefty.

Assignments and reference counting are thread safe as explained here

To satisfy thread safety requirements, the reference counters are typically incremented using an equivalent of std::atomic::fetch_add with std::memory_order_relaxed (decrementing requires stronger ordering to safely destroy the control block).

If multiple threads access same shared_ptr you can have a race condition.

If multiple threads of execution access the same shared_ptr without synchronization and any of those accesses uses a non-const member function of shared_ptr then a data race will occur; the shared_ptr overloads of atomic functions can be used to prevent the data race.

Your function reset is non const so falls on that category. You need to use mutex or another synchronization mechanism.

http://en.cppreference.com/w/cpp/memory/shared_ptr

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.