为什么这个multiset打印代码会永远循环?

时间:2012-11-30 14:02:45

标签: c++ algorithm multiset

我想打印出multiset中的每个重复项,但不知何故迭代器对我来说很奇怪。如何修复此代码?这段代码导致了一个永远的循环,让我感到惊讶。

#include <set>
#include <iostream>
#include <sstream>

static void print_duplicate(const std::multiset<int>& mset)
{
  std::stringstream error_msg;
  for (auto it = mset.begin(); it != mset.end(); ++it)
    {
      unsigned count = mset.count(*it);
      if (count < 2)
        continue;

      error_msg << "Duplicated numbers found:\n";

      for (unsigned i = 0; i < count; ++it, ++i)
        error_msg << "\tNum:" << *it << "\n";
    }

  std::cout << error_msg.str();
}

int main()
{
  std::multiset<int> mset;

  // fill it
  mset.insert(1);
  mset.insert(1);
  mset.insert(1);

  print_duplicate(mset);
}

修改 我在周期结束时添加了一个< - p>

  for (unsigned i = 0; i < count; ++it, ++i)
    error_msg << "\tNum:" << *it << "\n";
  --it; // this line fix it
}

5 个答案:

答案 0 :(得分:3)

在外部循环中,您可以多次增加it。因此,条件it != mset.end()可能永远不会成立,因为已经跳过了结尾。增加一个过去的迭代器是未定义的行为,这意味着它也可能无声地失败。

一种可能的解决方案可能是检查内部it != mset.end()循环中的for

for (unsigned i = 0; (i < count) && (it != mset.end()); ++it, ++i)
    error_msg << "\tNum:" << *it << "\n";

答案 1 :(得分:3)

for (unsigned i = 0; i < count; ++it, ++i)当此循环结束时,it将等于mset.end(),并且由于您仍然拥有主循环中的其他++it,因此您将获得不同的内容mset.end()因此程序永远不会结束。

答案 2 :(得分:2)

问题似乎是你在没有检测到的情况下滑过终点。在您创建的mset中,只有1个。这意味着count将为3,嵌套fori上的那个)将执行3次;完成后,it将等于mset.end()。然后控制到达外部for的末尾,it增加,变得非法,更重要的是,与mset.end()不同。这意味着外部循环永远不会终止。

答案 3 :(得分:1)

快速修复:在内循环后添加一行:it - ;

在Angew的回答中解释了原因。

答案 4 :(得分:0)

将for循环更改为:

for(std::container::iterator it=mset.begin(), it_next=it; it!=mset.end(); it=it_next) {
  ++it_next;
  ...
}

基本上,您正在跳过循环结束,因为您正在针对迭代器检查变量。仅增加辅助迭代器可以防止这种情况发生。