矢量迭代器在for循环中不可解除引用

时间:2013-09-05 12:54:40

标签: c++ vector

我正在使用一个循环来计算输入单词的次数然后打印单词以及输入的次数,这有效但从不打印最后一个单词,我按字母顺序排序。在打印最后一个单词之前,它错误地说迭代器不是可解除的。这是我的循环代码:

for (vector<string>::iterator it = v.begin() ; it != v.end(); ++it)
    {
        if (*it == *(it+1))
        {
        count++;
        }
        else if (*it != *(it+1))
        {
                count++;
            cout << *it << " ---- " << count << endl;
            count=0;
        }
    }

5 个答案:

答案 0 :(得分:21)

您的代码有未定义的行为 - 假设it指向v的最后一个元素,那么您试图在v.end()中取消引用*(it+1)

if (*it != *(it+1)

STL迭代器,end不指向最后一个元素; end()返回一个迭代器,表示容器中元素的结尾。结尾是后面的位置最后一个元素。这样的迭代器也称为 past-the-end迭代器

因此,begin()和end()定义半开范围,其中包含第一个元素,但排除最后一个

 --------------------------------
 |  |   |   |   |   |   |   |   |
 --------------------------------
  /\                               /\      
begin()                            end() 

对于您要实现的目标,请查看std::adjacent_find

auto it = std::adjacent_find(v.begin(), v.end());

if (it != v.end())
{
  count ++;
}
else
{
   cout << *it << " ---- " << count << endl;
}

答案 1 :(得分:1)

当你说完最后一句话并尝试执行时:

if (*it == *(it+1))

it+1指向v.end(),它是一个有效的迭代器,但不是derefernceable。因此错误。

答案 2 :(得分:1)

当它在结束迭代器之前是一个时,你在这里有一个问题:*(it+1)因为这会尝试取消引用结束迭代器,这是无效的。

我不确定在这种情况下你希望你的逻辑做什么,但在做这些事之前你可以用if (it+1 != v.end())检查这个。

答案 3 :(得分:1)

it == v.end() - 1时,您尊重(it+1)所以v.end(), 和deference v.end()是未定义的行为。

答案 4 :(得分:0)

因为当it接近结束时,it+1即将结束,并且您尝试在if运算符中取消引用它。