Take the 2-minute tour ×

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;

    //Do cleanup work with ob

/* Add Event response in Thread B */
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)
    //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?

share|improve this question
Are you synchronising access to objects in any way? –  Alex Korban Feb 5 '12 at 6:01
No. I figured since I was making a copy of objects before iterating through them it would be unnecessary. Why and how would synchronizing access prevent the objects from being deleted anyway? –  BigMacAttack Feb 5 '12 at 6:13
See Nicol's answer. STL containers aren't thread-safe. –  Alex Korban Feb 5 '12 at 6:57

1 Answer 1

up vote 11 down vote accepted

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.

share|improve this answer
Thanks Nicol. This helped me to fix the problem. I went ahead and created this to solve my problems with concurrency. –  BigMacAttack Feb 6 '12 at 20:31

Your Answer


