迭代器未按预期运行

Posted

技术标签:

【中文标题】迭代器未按预期运行【英文标题】:Iterator not acting as expected 【发布时间】:2012-12-17 10:42:52 【问题描述】:

代码:

std::vector<std::string>::iterator first = iter;

if( ++iter != iter_is_pointing_to_this_vector.end())

  ...

当“首先”取消引用迭代器时,会发生分段错误。当注释掉取消引用时,程序只是在 if 语句处停止并且不会继续。 iter 的递增显然没有达到我的预期:我想确保有问题的向量有或没有更多成员传递“iter”指向的项目。

这种行为的原因是什么?

【问题讨论】:

iter 指向什么?请显示完整的代码以重现此内容。 会不会是iter在增量之前已经在end()了? 您可能打算使用iter + 1,但这似乎仍然是错误的。 好的。 vector.end() 是指向向量过去 的第一个元素的指针。因此,当iter == vector.end() 为真时, (*iter) 已经导致未定义的行为或崩溃。此外,我不确定当您在已经指向结束的迭代器上执行 ++iter 时会发生什么。也许甚至这是被禁止的。我不记得文档是怎么说的:)。可能当iter == v.end() 然后++iter 也会导致未定义的行为。 您正在“在 while 循环的底部”增加迭代器,但您也在代码 sn-p 的 if 语句中增加了迭代器。这意味着迭代器在循环内增加了两次。您的 while 循环不会终止,因为当您在 while 条件下检查迭代器时,迭代器将超出 end()。正如 Pubby 所说,您可能指的是iter + 1,而不是++iter 【参考方案1】:

好的,评论太长了,所以我会发布它作为答案,但它可能不完整。

++iter 这样的构造将推进一个迭代器。因此,如果您的线路在循环中,另一条 ++iter 在其末尾,您将在每个循环中推进两次!。 ++iter 不会产生指向下一个元素的迭代器,而是将 iter 移动到它。

据我了解,您使用++iter != iter_is_pointing_to_this_vector.end() 检查下一个元素是否结束。确定当前元素是否是向量中的最后一个。但是你写的代码做了一些不同的事情。

要执行您想要的操作,您需要另一个迭代器,您可以将其设置为当前元素的下一个元素。

std::vector<std::string>::iterator = iter = v.begin();
std::vector<std::string>::iterator = iter2 = v.begin();
++iter2;
while( ... )
  if(iter2 != v.end() )...
  ++iter2; ++iter;

当然,您需要确保v 包含多个元素。 如果您的容器提供,您也可以使用reverse_iterator

typedef iter_t std::vector<std::string>::iterator;
iter_t = iter = v.begin();
std::reverse_iterator<iter_t> = iter2 = v.rbegin();
while( ... )
  if(iter != iter2.base() )...
  ++iter;

注意:base() 将反向迭代器转换为普通(正向)迭代器,因此可以比较它们。

编辑: 您似乎可以将reverse_iterator 与双向迭代器一起使用,这意味着它们也将实现递减操作。因此,由于您实际上并不需要反向迭代,只需要一个相对于end 的元素的迭代器,一种更简单的方法是:

typedef iter_t std::vector<std::string>::iterator;
iter_t = iter = v.begin();
iter_t = iter2 = v.end();
--iter2;
while( ... )
  if(iter != iter2)...
  ++iter;

【讨论】:

以上是关于迭代器未按预期运行的主要内容,如果未能解决你的问题,请参考以下文章

Sendgrid 替换包装器未按预期工作

Jsoup :has() 选择器未按预期工作

映射迭代器未定义 React.JS

Nodejs 代码未按预期执行

WaveFront .obj 加载器未按应有的方式显示对象(VBO 和 VAO)

具有比较器的优先级队列未按预期工作