Sunday, 2 March 2014

Debug Assertion Failed! this->_Has_container()

What is wrong with the following? The intention is to remove an element from a container which matches some criteria.

#include <vector>
using namespace std;
void main()
{
    vector<int> list;
    list.push_back(10);
    list.push_back(20);
    list.push_back(30);
    for (vector<int>::iterator it = list.begin(); it != list.end(); it++)
    {
        if ((*it) == 20)
        {
            list.erase(it);
        }
    }
}


When run in Visual C++, one might see a message like this:

Debug Assertion Failed! Expression: ("this->_Has_container()", 0)

Certain container operations invalidate iterators. For the vector above, erase() is the culprit. If we add a line to the if clause:

if ((*it) == 20)
{
    list.erase(it);
    it++;
}


and set a breakpoint on both lines, we see the second line will fail the assertion. This is because element pointed to by the iterator has been erased and the iterator is no longer valid.

For the purposes above, a quickfix would be to add the break statement:

if ((*it) == 20)
{
    list.erase(it);
    break;
}


so that execution leaves the loop and the iterator goes out of scope anyway.

Homework: For a vector with elements 10,20,20,30, simply adding a break statement would cause only one of the two 20s to be erased. How would one erase both?

No comments:

Post a Comment