简体   繁体   中英

C++ Vector iterator not dereferencable after more data added

Comrades,

The following does not work:

vector<string>::iterator c;

for( c = holdtype.begin(); c != holdtype.end(); c++)
{ 
    if( *c == "preposition" )
    {
        c++; 
        if( *c == "unknown" )
        {       
            c++;  
            if( *c == "unknown" )
            {
                c++;  
                if( *c == "unknown" )
                {
                    cout <<endl <<"This should be a verb " << *c;
                }
            }
        }
    } 
}

The strange thing is that it works for a certain amount of data. As soon as it goes above roughly 30 words it stops working and gives me the "not dereferencable error".

I have tried this and it gives the same results:

vector<string>::iterator c;
c = holdtype.begin();

while( c != holdtype.end())
{ 
    if( *c == "preposition" )
    {
        if( c != holdtype.end() ) { c++; } else { break; }
        if( *c == "unknown" )
        {       
            if( c != holdtype.end() ) { c++; } else { break; }
            if( *c == "unknown" )
            {
                if( c != holdtype.end() ) { c++; } else { break; }
                if( *c == "unknown" )
                {
                    cout <<endl <<"This should be a verb " << *c;
                }
            }
        }
    } 
    if( c == holdtype.end() ) { break; } else {c++;}
}

I have been trying to figure this out for a few days now, I am a beginner.

Imagine your vector contains just one string, "preposition".

Now your execution does this:

  1. Start iterating, iterator points to first vector element
  2. Compare dereferenced iterator to "preposition"
  3. Match!
  4. Increment iterator. Iterator now is equal to holdtype.end() .
  5. Attempt to dereference iterator to compare it to "unknown" (code: *c == "unknown" )
  6. Fail, since you cannot get the "contents" of the std::vector::end() special value.

You're effectively trying to access an element beyond the end of your vector, in the first piece of code. In the second, all the c != holdtype.end() checks successfully guard against this.

Your second version is almost correct, but you need to check if c is valid after you increment and before you dereference:

vector<string>::iterator c;
c = holdtype.begin();

while( c != holdtype.end())
{ 
    if( *c == "preposition" )
    {
        ++c;
        if( c == holdtype.end() ) { break; }
        if( *c == "unknown" )
        {       
            ++c;
            if( c == holdtype.end() ) { break; }
            if( *c == "unknown" )
            {
                ++c;
                if( c == holdtype.end() ) { break; }
                if( *c == "unknown" )
                {
                    cout <<endl <<"This should be a verb " << *c;
                }
            }
        }
    } 
    ++c;
}

You are potentially dereferencing the end iterator in both cases. Suppose that your vector ends with "preposition".

In the first example you have no protection at all against hitting end() . So when you hit that last "preposition" you are going to dereference.

In the second example, you're protection is backwards. You need to test whether the iterator is at the end after incrementing, not before.

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