简体   繁体   中英

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++;
        }
    }

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.

您确实希望查看诸如remove_if之类的STL算法,而不是手动执行此操作。

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.

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.

删除向量中的元素会使所有迭代器无效。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM