矢量迭代器> vector.end()即使矢量不应该被重新分配

时间:2013-07-18 01:26:43

标签: c++

首先:如果有人能想到更简洁的方式,我很乐意更新标题中的问题。

情况如下:

我有一个矢量作为类成员。从矢量中提取元素后,使用以下内容:

inline int currentToken()
{
    /* __it is of type std::vector <int>::iterator */

    return (__it < __tokens.begin()) ? Syntax::OUT_OF_RANGE_BEGIN :
           (__it > __tokens.end())   ? Syntax::OUT_OF_RANGE_END :
           *__it;
}

返回的整数完全符合预期(在这种情况下,为65,这应该是它)。

然而现在情况变得棘手了。当遇到这个特殊的标记时,它会引发一个新的事件链,并且需要丢弃向量中的前一个标记。

首先,我调用类''saveLocation'成员函数,这是一个内联的快速:

__saved_it = __it;

然后,我调用'truncateHead'成员函数,这是发生错误的地方。在代码之前,我想指出以上都没有以任何方式更改向量,因此绝对没有理由重新分配向量的内存。

__it = __tokens.erase(__tokens.begin(), __saved_it+1); //segfault

有些调试显示__it某种方式__tokens.end()大于__begin,即使它仍然大于__tokens.begin() 取消引用数字'65 '正如所料。

它如何不在__tokens.end()saveLocation之间?

事实上,这种情况已经存在于上面的currentToken()方法中。

请记住,saveLocation()后面会紧跟currentToken,如果迭代器已经超出范围,OUT_OF_RANGE_END会返回{{1}}的整数表示形式,我感到很沮丧

完全彻底。

2 个答案:

答案 0 :(得分:3)

tokens.end()返回结束迭代器。也就是说,它已经超出了范围。

比较迭代器是否大于(>)并超过结束迭代器没有意义,因为迭代器的范围仅从begin()end()。由于同样的原因,检查迭代器是否小于begin()返回的迭代器也没有意义。

这意味着无法检查迭代器是OUT_OF_RANGE_BEGIN还是OUT_OF_RANGE_END。您只能检查它是否在有效范围内。

可以检查迭代器是否大于或等于>=返回的迭代器(begin())。

当您检查__it是否超过最后一个元素时,您应该评估迭代器是否不等于tokens.end()

E.g。你应该检查像

这样的东西
return (__it >= __tokens.begin()
     && __it != __tokens.end()) ? *__it : Syntax::OUT_OF_RANGE;

这还要求您不要将迭代器增加到容器的末尾迭代器之外。访问已经超过end() - 迭代器的迭代器指向的内存将导致未定义的行为。

答案 1 :(得分:2)

迭代器比较仅对指向相同范围的迭代器有效。测试迭代器是<容器的begin迭代器还是>容器的结束迭代器没有做任何有意义的事情。