// thread 0
// thread 1
for (itr = list_x.begin(); itr != list_x.end(); itr++)
In thread zero, what specifically happens behind the scenes is that the
push_back() method first allocates a new node, then hooks the new node
into the list, first by modifying the lists pointers, and then by
modifying the nodes pointers at which point the new node is linked in
and in a stable state. In the second thread, the variable itr is
assigned the first node in the list, or more specifically list_x->next.
In the middle condition of the for() statement, the iterator is checked
to ensure that it does not equal the end of the list, which behind the
scenes is actually defined as being list_x (the list is circular).
Assuming this condition is true, then the iterator is dereferenced and a
member method is called.
However, if in the process of hooking in the new node during
push_back(), this new node is traversed by the for() loop in the second
thread, it is possible that itr->next does not point to a valid node in
the list, and not to the node returned by end(). Thus when the iterator
is assigned to itr->next, it can point to an invalid section of memory,
and then when the member method is called, execution can occur in an