0

I have below code. The code doesn't work in Visual Studio. But in another compiler, such as onlinegdb.com, it works fine. And output "

#include <iostream>
#include <set>
using namespace std;

int main()
{
    set <int> ms{1,2,3,4,5};
    set <int>::iterator it;

    int i = 0;
    for (it = ms.begin(); it != ms.end(); ++it) {
        if (i == 4)  {
            ms.erase(it);               // I know if I want to remove the last element, I can just code "ms.erase(--ms.end())" without the need of a loop
            // it = ms.erase(it);       // replacing the above link with this line doesn't work neither
        }
        i++;
    }

    for (auto x : ms) {
        cout << x << " ";
    }
    return 0;
}

Output:

  • If run on onlinegdb.com: 1 2 3 4
  • If run on Visual Studio 2019, error Expression: cannot increment value-initialized map/set iterator

I think when the last element is removed, iterator it will be set as end. So the loop will break.

Can anyone explain for me why stuff cannot work in Visual Studio? Thank you so much.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
Triho
  • 29
  • 1
  • 5
  • Please don't put "resolved" or "solved" in the title. Stack Overflow has other mechanisms of doing the same thing, like marking a question as duplicate and/or [accepting an answer](/help/someone-answers). – wjandrea Jul 05 '22 at 15:53

2 Answers2

1

Erasing the element invalidates the iterator. Using the iterator returned from erase is the right thing to do, but that iterator references the element past the one erased, hence you should only increment when you do not erase:

for (it = ms.begin(); it != ms.end(); ) {   // do not increment here
    if (i == 4)  {            
        it = ms.erase(it);
    } else {
        ++it;                               // but only when you do not erase
    }
    ++i;
}

For more details on iterator invalidation I refer you to Iterator invalidation rules for C++ containers.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
1

You must use what the erase function returns.

And if you erase you should not increase the iterator.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621