I have an STL map that contains shared pointers to objects that are manipulated in multiple threads. The object the shared_ptr owns is being deleted while a smart pointer is still present in the container and/or the scope of other functions. All shared_ptr instances are passed by value (so its not a problem with a misuse of references). I was under the impression from this source here that as long as an instance of shared_ptr exists (that was copied from an existing shared_ptr) the object it owns will not be deallocated.
Here is basically what I'm doing:
/* Remove Event response in Thread A */
std::map<std::string, std::shared_ptr<object>>::iterator it = objects.find(id);
if(it != objects.end())
{
std::shared_ptr<object> ob = it->second;
objects.erase(it);
//Do cleanup work with ob
}
/* Add Event response in Thread B */
std::map<std::string, std::shared_ptr<object>>::iterator it = objects.find(id);
if(it == objects.end())
{
std::shared_ptr<object> ob(new object(id));
objects[id] = ob;
//Do setup work with ob
}
/* Duty Cycle Event response in Thread C (very frequent) */
//Take snapshot of objects so Remove Event does not invalidate iterators of duty cycle
std::map<std::string, std::shared_ptr<object>> temp_objects = objects;
for(std::map<std::string, std::shared_ptr<object>>::const_iterator it = temp_objects.begin(); it != temp_objects.end(); ++it)
{
std::shared_ptr<object> ob = it->second;
//Access violation can (but doesn't always) occur when dereferencing ob (ob is empty)
}
What am I doing wrong? Am I misusing shared pointers or making improper assumptions about how they operate?
The reference count for shared_ptr
objects is atomic; this is required by C++11. However, what is not required is that std::map
operations are atomic. They're certainly not.
It is not guaranteed that you can insert from one thread and delete from another and still maintain the integrity of the contents of the map
. So unless you put in your own mutexes or some other synchronization, to prevent race conditions on the map
itself, your code will break.
This has nothing to do with shared_ptr
; that's just the symptom of the problem. This is about the map
that contains them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With