3

i have declared a map below using stl and inserted some values in it.

#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;
}

When i executed the above written code it ended up in an infinite loop. Can someone tell me why it does so? I am incrementing the value of iterator it and then it gets stored in it which should get incremented next time the loop is executed and eventually it should terminate normally.Am i wrong?

melpomene
  • 84,125
  • 8
  • 85
  • 148
  • 1
    Perhaps this can give some hints: https://stackoverflow.com/questions/26281979/c-loop-through-map – crazyGamer Aug 05 '17 at 14:28
  • 1
    [You should not include ``](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h). – melpomene Aug 05 '17 at 14:40

3 Answers3

4

The bad line is it = it++;. It is undefined behavior! Because it is not defined, when it is increased, in your case it is increased before the assingment to itsself again, that the value of it before it is increased is assigned to it again and so it keeps at the first position. The correct line would be it = ++it; or only ++it;/it++;, because it changes itsself.

Edit

That is only undefined with the builtin types, but in here that is defined by the source-code of the map in the stl.

cmdLP
  • 1,658
  • 9
  • 19
  • 4
    `it = ++it;` should not be recommended as the correct line. Yes, technically it is correct, but all it communicates to a reader is "whoever wrote this probably doesn't understand what `++` does". –  Aug 05 '17 at 15:08
1

If you try doing something similar with an int, you'll get a warning:

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]

However, when you're using a class (std::map::iterator) which has operator overloading, the compiler probably isn't smart enought to detect this.

In other words, what you're doing is a sequence point violation, so the behavior is undefined behavior.

lost_in_the_source
  • 10,998
  • 9
  • 46
  • 75
1

The post-increment operation would behave like this:

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

So, what happens to your increment step is that iterator it would get overwritten by the copy of its original value. If the map isn't empty, your loop would remain stuck on the first element.

jxh
  • 69,070
  • 8
  • 110
  • 193