Erasing from middle of a list problem

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Angus

    Erasing from middle of a list problem

    If I want to erase all list items with a value of say 3 as below:

    std::list<intmy list;
    mylist.push_bac k(3);
    mylist.push_bac k(4);
    mylist.push_bac k(5);
    mylist.push_bac k(6);

    for(std::list<i nt>::iterator it = mylist.begin(); it !=
    mylist.end(); ++it) {
    if(*it == 3) {
    std::cout << "deleting 3" << std::endl;
    mylist.erase(it );
    }
    }

    I get an access violation in the loop iteration after an erase. What
    is the recommended way to deal with this? ie iterate through a
    container removing elements which meet a criterion? remove?

    A
  • fungus

    #2
    Re: Erasing from middle of a list problem

    On Nov 1, 11:52 am, Angus <anguscom...@gm ail.comwrote:
    >
    I get an access violation in the loop iteration after an erase.
    Yep, you just freed the memory referenced by "it".
    What
    is the recommended way to deal with this? ie iterate through a
    container removing elements which meet a criterion?  remove?
    >
    std::list<int>: :iterator it = mylist.begin();
    while (it != mylist.end()) {
    if(*it == 3) {
    std::cout << "deleting 3" << std::endl;
    it = mylist.erase(it );
    }
    else {
    ++it;
    }
    }

    Comment

    • =?ISO-8859-1?Q?Marcel_M=FCller?=

      #3
      Re: Erasing from middle of a list problem

      Angus schrieb:
      for(std::list<i nt>::iterator it = mylist.begin(); it !=
      mylist.end(); ++it) {
      if(*it == 3) {
      std::cout << "deleting 3" << std::endl;
      mylist.erase(it );
      }
      }
      >
      I get an access violation in the loop iteration after an erase.
      Of course, you just invalidated your iterator by erasing its element.
      What
      is the recommended way to deal with this?
      erase returns an iterator to the next valid element.

      ie iterate through a
      container removing elements which meet a criterion? remove?
      The algorithm remove_if will do the job for you.


      Marcel

      Comment

      • Daniel T.

        #4
        Re: Erasing from middle of a list problem

        Angus <anguscomber@gm ail.comwrote:
        If I want to erase all list items with a value of say 3 as below:
        >
        std::list<intmy list;
        mylist.push_bac k(3);
        mylist.push_bac k(4);
        mylist.push_bac k(5);
        mylist.push_bac k(6);
        >
        for(std::list<i nt>::iterator it = mylist.begin(); it !=
        mylist.end(); ++it) {
        if(*it == 3) {
        std::cout << "deleting 3" << std::endl;
        mylist.erase(it );
        }
        }
        >
        I get an access violation in the loop iteration after an erase. What
        is the recommended way to deal with this? ie iterate through a
        container removing elements which meet a criterion? remove?
        The answers to date missed something important.

        mylist.remove( 3 );

        will do exactly what you want.

        The 'remove' and 'remove_if' algorithms are highly inefficient if used
        on a list, there is no reason to reseat values in nodes when dealing
        with a linked list.

        Writing the loop yourself is wasteful in this case.

        Comment

        Working...