为什么这是一个无限循环

时间:2017-08-05 14:18:47

标签: c++11

我已经使用stl在下面声明了一个地图,并在其中插入了一些值。

#include<bits/stdc++.h>
int main()
{


map<int,int> m;
m[1]=1;
m[2]=1;
m[3]=1;
m[4]=1;
m[5]=1;
m[6]=1;

for(auto it=m.begin();it!=m.end();)
{
  cout<<it->first<<" "<<it->second<<endl;
  it=it++;
}

return 0;
}

当我执行上面编写的代码时,它最终处于无限循环中。有人能告诉我它为什么这样做吗? 我正在递增迭代器的值,然后它被存储在它中,它应该在下次循环执行时递增,最终它应该正常终止。我错了吗?

3 个答案:

答案 0 :(得分:3)

坏线是it = it++;。这是未定义的行为!因为它没有被定义,所以当它增加时,在你的情况下,它再次在它自己的辅助之前增加,它之前的值增加再次分配给它,所以它保持在第一个位置。 正确行将为it = ++it;或仅++it; / it++;,因为它会自行更改。

修改

这只是内置类型未定义,但在这里由stl中地图的源代码定义。

答案 1 :(得分:1)

如果您尝试使用int执行类似操作,则会收到警告:

int nums[] = { 1, 2, 3, 4, 5 };
for (int i = 0; i < sizeof nums / sizeof *nums; ) {
    cout << nums[i] << '\n';
    i = i++;
}

warning: operation on 'i' may be undefined [-Wsequence-point]

但是,当您使用具有运算符重载的类(std::map::iterator)时,编译器可能并不聪明地检测到它。

换句话说,您所做的是违反序列点,因此行为是未定义的行为。

答案 2 :(得分:1)

后增量操作的行为如下:

iterator operator ++ (int) {
    auto copy = *this;
    ++*this;
    return copy;
}

因此,增量步骤会发生什么,迭代器it会被原始值的副本覆盖。如果map不为空,则循环将保持在第一个元素上。