A few years ago, while working in the
RTA, I ran into a reasonably complicated problem where a list would be traversed at two portions of the code at the same time. That is, say that I have a list A which I am traversing and performing actions on each of the contents in the list. I have reached object X and am performing an action on it. The effect of this action is to destroy object X+1 and remove it from list A. However, the iterator on list A has already grabbed a pointer to the next object (X+1), and when the loop attempts to access the memory address of X+1, it is accessing invalid memory which may cause a dreaded segmentation violation.
This problem was quite difficult to debug and eventually I managed to produce a test case which demonstrated the problem. The programming language at the time was C++, and the test case looked like this:
#include <stdio.h>
#include <list>
using ::std::list;
void pathologicalCase ( list < char * > &rList )
{
for ( list < char * >::iterator aOuterNext = rList.begin(),
aOuterIter = rList.begin(), aOuterEnd = rList.end();
aOuterIter != aOuterEnd;
aOuterIter = aOuterNext )
{
++aOuterNext;
printf ( "Outer is %s\n", (*aOuterIter ) );
for ( list < char * >::iterator aInner = rList.begin(),
aInnerNext = rList.begin(),
aInnerEnd = rList.end();
aInner != aInnerEnd;
aInner = aInnerNext )
{
++aInnerNext;
printf ( "Inner is %s\n", (*aInner) );
if ( 0 == strcmp ( *(aInner), "String B" ) )
{
free ( *(aInner) );
rList.erase ( aInner);
}
}
}
}
int main ( int argc, char **argv )
{
list < char * > aList;
aList.push_back ( strdup ( "String A" ) );
aList.push_back ( strdup ( "String B" ) );
pathologicalCase ( aList );
}
It has taken me quite some time to get the 'geshi' syntax highlighter to display the above code block correctly, so I am going to stop here for now and then post the C++ code I used to 'fix' the above problem.