简体   繁体   English

添加更多数据后,C ++ Vector迭代器不可解除

[英]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". 一旦超过大约30个字,它就会停止工作,并给我“不可撤消的错误”。

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() . 迭代器现在等于holdtype.end()
  5. Attempt to dereference iterator to compare it to "unknown" (code: *c == "unknown" ) 尝试取消引用迭代器以将其与“未知”进行比较(代码: *c == "unknown"
  6. Fail, since you cannot get the "contents" of the std::vector::end() special value. 失败,因为您无法获得std::vector::end()特殊值的“内容”。

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. 在第二个中,所有c != holdtype.end()检查都成功地防止了这种情况。

Your second version is almost correct, but you need to check if c is valid after you increment and before you dereference: 您的第二个版本几乎是正确的,但是在增加之后和取消引用之前,您需要检查c是否有效:

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() . 在第一个示例中,您根本无法避免碰到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. 您需要测试迭代器是否在递增之后而不是递增之后结束。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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