mouse_00
mouse_00

Reputation: 683

std::list::erase does not invalidate other iterators and references

I read in cppreference that erase does not affect iterators and references other than erased ones. But if I don't understand why following code does not work:

#include <iostream>
#include <list>

int main()
{
  std::list<int> lst;
  lst.push_back(5);
  lst.push_back(10);
  lst.push_back(20);

  int i = 0;
  for (auto it = lst.begin(); it != lst.end(); ++it) // FIRST LOOP
  {
    if (i == 1) { lst.erase(it); }
    ++i;
  }

  for (auto el : lst) // SECOND LOOP
  {
    std::cout << el << std::endl;
  }

  return 0;
}

First loop never stops which causes Process finished with exit code 139 (interrupted by signal 11: SIGSEGV). But I don't erase everything works fine. So what is the problem?

UPD: Tried to change

...
for (auto it = lst.begin(); it != lst.end(); ++it) // FIRST LOOP
...

to

...
auto end = lst.end();
  for (auto it = lst.begin(); it != end; ++it) // FIRST LOOP
...

but it did not help

Upvotes: 0

Views: 180

Answers (1)

lorro
lorro

Reputation: 10880

When you delete the element at it, you cannot increment it anymore. Therefore, you need to use this instead:

if (i == 1) { it = lst.erase(it); }

Also, you need to solve not to increment it in this case. So likely the increment would go inside the loop:

int i = 0;
for (auto it = lst.begin(); it != lst.end(); ) // FIRST LOOP
{
    if (i == 1)
    {
        it = lst.erase(it);
    }
    else
    {
        ++it;
    }

    ++i;
}

Upvotes: 4

Related Questions