4

I am learning C++ and I am working my way double linked lists, but I noticed something very peculiar when I was trying to delete elements from my list.

Problem: I am inserting an element before the value of 2 in my list , numbers, and then I am trying to delete any element that has the value 1.

Expected: After I call erase() in my conditional statement in my first loop my list, numbers, should get adjusted. The only values that numbers should should contain 0,1234,2,3.

Observed: My list numbers contains the values 0,1,1234,2,3. It is as if nothing was erased.

Code Example:

#include "stdafx.h"
#include <iostream>
#include <list>

using namespace std;

int main()
{
   list<int> numbers; 

   numbers.push_back(1);
   numbers.push_back(2);
   numbers.push_back(3);
   numbers.push_front(0);

   list<int>::iterator it = numbers.begin();
   it++;
   numbers.insert(it, 100);
   cout << "Element: " << *it << endl;

   list<int>::iterator eraseIt = numbers.begin();
   eraseIt++;
   eraseIt = numbers.erase(eraseIt);
   cout << "Element: " << *eraseIt << endl;

   for (list<int>::iterator it = numbers.begin(); it != numbers.end(); it++)
   {
      if (*it == 2)
      {
         numbers.insert(it, 1234);
      }

      if (*it == 1)
      {
         it = numbers.erase(it);
      }
      else
      {
         it++;
      }
   }

   for (list<int>::iterator it = numbers.begin(); it != numbers.end(); it++)
   {
      cout << *it << endl;
   }

    return 0;
}

What can I try next?

halfer
  • 19,824
  • 17
  • 99
  • 186
Evan Gertis
  • 1,796
  • 2
  • 25
  • 59
  • 1
    Your loop is invalid. If you insert or erase in the list, it invalidates the iterator. – Barmar Feb 08 '18 at 02:04
  • 2
    @Barmar No, [std::list::insert](http://en.cppreference.com/w/cpp/container/list/insert) doesn't invalidate iterators, and for `erase` OP has reassigned `it` with the returned iterator from `erase`. – songyuanyao Feb 08 '18 at 02:13

2 Answers2

5

You should remove the it++ at the end of the for loop declaration, because it might be increased inside the for loop too; when it gets inscreased twice some elements will be skipped. i.e.

for (list<int>::iterator it = numbers.begin(); it != numbers.end(); )

LIVE

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
0

It's quite enough to remember the next iterator value before doing any deletion/insertion at the current position. This will help you to keep yourself careless about what and when are your modifications concretely doing.

list<int>::iterator it = numbers.begin();
while (it != numbers.end()) {
{
list<int>::iterator next_it = it;
++next_it;

// Do your insertion or deletion here

it = next_it;
}
AndreyS Scherbakov
  • 2,674
  • 2
  • 20
  • 27