I have pointers to the elements in some other object. Is it safe to have? I know that vector will move all the objects when it needs more space so pointers will be invalidated.
mylist.push_back(MyObj(1));
if(someCond)
{
_myLastObj = &mylist.back();
}
_myLastObj
is of type MyObj*
If I had used a vector, the object would have been moved to a different location and the pointer would be pointing to garbage. Is it safe with a list?
std::list
are invalidated only if that same element is removed from the list. Since your code never removes anything from the list, your pointers are safe.For a concrete reason why you need the lock, consider for example that list::push_back
is permitted to do the following, in this order:
If your reader thread comes in between 2 and 3, then it will go from the previous tail, to the new node, then try to follow an uninitialized pointer. Boom.
In general though, you need synchronization because it's the only way to guarantee that changes made in the writer thread are published to the reader thread in any kind of sensible order (or at all).
Your code should be correct if you imagine that different threads run on different planets, each with its own copy of your program's memory, and transmit changes to each other (a) when you use a synchronization object (or atomic variable in C++11), plus (b) when you don't use a synchronization object but transmitting some particular partial change will break your code (such as one half of a two-word object or in this case one of two pointer writes that you need to occur in a particular order). Sometimes this model is more conservative than strictly necessary, and results in slower code. But a less conservative model relies on implementation-specific details of the threading system and memory model.