Search code examples
c++iteratorunhandled-exceptionerasestdlist

How to properly point back to std::list after erasing en element (double for loop)?


I want to erase an element from the std::list and then point back to this list but when I do it this way

for(std::list<CvRect>::iterator it = listOfCvRects.begin(); it != listOfCvRects.end(); it++)
{
    for(std::list<CvRect>::iterator jt = listOfCvRects.begin();  jt != listOfCvRects.end(); jt++)
    {
        if( it == jt )
        { continue;}

        if( (jt->x) > (it->x) //.. more conditions...)
        {
            jt = listOfCvRects.erase(jt);
            //OR 
            //listOfCvRects.erase(jt++);
        }
    }

}

I got and unhandled exception : iterator is unincrementable


Solution

  • I believe the problem is that in some cases (those where you delete an element), you are double incrementing the iterator. Your for loop looks like this:

    for(std::list<T>::iterator jt = l.begin();  jt != l.end(); jt++) {
        ....
    }
    

    But inside of it you are doing something like this:

    jt = l.erase(jt);
    

    So, if the case happens that you do the erase, you erase it and at the same time, set the iterator to the next element... But, you also increment it with the jt++!

    The simple approach to fixing this is re-write the for loop slightly to fit this form factor:

    for(std::list<T>::iterator it = l.begin(); it != l.end(); ) { // notice no increment!
        // ...
        if(cond) {
            it = l.erase(it);
        } else {
            ++it;
        }
    }
    

    so you are doing one or the other increments, but never both.