1

I wrote this simple test program. But i can't understand what happens here. Because there is a strange thing in the output:

std::list<std::pair<double,double>> l; l.push_back({0.3,0.9}); l.push_back({-0.3,0.5}); l.push_back({0.3,0.7}); l.push_back({1.2,1.83}); for(auto it=l.begin(); it!=l.end(); ++it){ double lx= it->first + 0.01; double ly= it->second + 0.01; it->first = lx; it->second = ly; if(lx < 0.0 || lx > 1.0 || ly < 0.0 || ly > 1.0){ it = l.erase(it); } 

If i print the list, i get:

0.32, 0.92 0.31, 0.71 

Why does the iterator goes back to the first element (twice +0.1) ?

5
  • 1
    The ==0 in the if is superfluous, in fact the whole if is useless because the it != end() will take care of that. And I'm not sure why you said the first element is there twice? It looks like youre removing elements at position 1 and 3 and therefore printing elements 0 and 2. Commented Dec 1, 2016 at 18:26
  • Thanks for the answer. Yes it prints Element 0 and 2, but it adds 0.1 twice at the first element. I can't understand why: it should be (0.31, 0.91) and (0.31,0.71) Commented Dec 1, 2016 at 18:29
  • Just as an aside, a typical pattern for doing this is the erase-remove idiom with l.erase(std::remove_if(...), l.end()). Commented Dec 1, 2016 at 18:33
  • @arch under the standard, modifying while removeing is illegal. Annoying, but true. Commented Dec 1, 2016 at 18:39
  • see: stackoverflow.com/a/263958/14065 Commented Dec 1, 2016 at 18:45

1 Answer 1

7
it=list.erase(it); 

This erases the element at it. It then returns the iterator location after the erased element was.

When your for loop finishes an iteration, it advances it, via ++ then checks if it equals end().

So your loop both skips the element after each one erased. Not good. And if it erases the last element it proceeds to advsnce the end iterator, which is illegal.

Remove ++it from the for loop header. At the bottom of the loop, either advance it or erase at it, not both nor neither.

The strange printing behaviour is due to UB. You increment data at location 0. You increment data at location 1, then delete it. You skip location 2. You increment data at location 3, then delete it. You advance past the end iterator (undefined behaviour). Then random stuff happens that just happens to increment data location 0 and 2 again. As a guess, ++ on the end iterator happens to loop back to the first element in your particular case (this is not guaranteed at all, but with UB anything can happen). The second loop then runs as normal, incrementing the data at the two elements and deleting nothing.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.