user98188
user98188

Reputation:

What does this code in "vector" mean? (C++)

I created a program, and it uses the vector.h #include, and iterators, etc... But when I run the program, under certain circumstances (I'm still trying to figure out what those would be) I get an assertion error refering me to line 98 of vector.h. I went to line 98 of vector.h and got this:

 #if _HAS_ITERATOR_DEBUGGING
        if (this->_Mycont == 0
            || _Myptr < ((_Myvec *)this->_Mycont)->_Myfirst
            || ((_Myvec *)this->_Mycont)->_Mylast <= _Myptr)
            {
            _DEBUG_ERROR("vector iterator not dereferencable");
            _SCL_SECURE_OUT_OF_RANGE;
            }

Can somebody please tell me what this means and what in my program is causing this assertion?

NB: Line 98, for the record, is the one that begins "_DEBUG_ERROR("vect..."

NB: This is the code in my program that I BELIEVE triggered the error, I'm not entirely sure, though.

CODE:

for(aI = antiviral_data.begin(); aI < antiviral_data.end();)
    {
        for(vI = viral_data.begin(); vI < viral_data.end();)
        {
            if((*aI)->x == (*vI)->x && (*aI)->y == (*vI)->y)
            {
                vI = viral_data.erase(vI);
                aI = antiviral_data.erase(aI);
            }
            else
            {
                vI++;
            }
        }
        if((*aI)->x >= maxx || (*aI)->x < 0 || (*aI)->y >= maxy || (*aI)->y < 0)
        {
            aI = antiviral_data.erase(aI);
        }
        else
        {
            aI++;
        }
    }

Upvotes: 1

Views: 1857

Answers (5)

Hexagon
Hexagon

Reputation: 6961

In addition to the accepted answer, and to elaborate on slavy13's answer -
(EDIT - and as mentioned by Josh, not directly relevant to this question - I'm leaving it here for reference).

Code (but not this code) sometimes assumes that you can remove elements from a vector, and keep iterating. This is a false assumption - once you remove an element from a vector, all other iterators following the removed element are invalidated - you can no longer assume they are correct, and "bad things" can happen if you keep using them.

The reason for this is because a vector actually stores information in an array form. When an element is removed, all following elements are copied one cell down. The iterators aren't updated accordingly.

It is strongly recommended to consult STL documentation whenever trying to do such things, because it is entirely possible such code would work on a certain implementation of STL accidentally, but fail on others.

Upvotes: 1

user44511
user44511

Reputation: 2851

erasing an element in a vector invalidates all iterators.

Upvotes: -2

beef2k
beef2k

Reputation: 2247

A small general comment: When checking an iterator for end(), do not use "<" but only "!=". So, the first lines of your code should look like:

for(aI = antiviral_data.begin(); aI != antiviral_data.end();)
{
  for(vI = viral_data.begin(); vI != viral_data.end();)
  {
    ...

However, as Josh already pointed, your specific bug is in line 7.

Upvotes: 5

Nikolai Fetissov
Nikolai Fetissov

Reputation: 84169

You really want to look at STL algorithms like remove_if instead of doing this stuff manually.

Upvotes: 7

Eclipse
Eclipse

Reputation: 45493

The runtime is detecting that you are dereferencing an iterator that is before begin() or after end().

Imagine if you delete the last item in the antiviral_data vector in line 7:

aI = antiviral_data.erase(aI);

aI gets set to antiviral_data.end(), and when you dereference it in line 14:

if((*aI)->x >= maxx ...

and also in line 5:

if((*aI)->x == (*vI)->x

You are dereferencing an out of bounds iterator.

The fix is to check that aI != antiviral_data.end() after the erase call to make sure you haven't hit the end of the vector before you continue on using it.

Upvotes: 10

Related Questions