c++stdlist

Erasing list elements step by step


I want to erase list elements one by one. Before removing any of list elements I want to see the whole list.

#include <iostream>
#include <list>
int main()
{
    std::list<int>numbers{0,1,2,3,4,5,6,7,8,9};
    auto it=numbers.begin();
    for(int i=0;i<10;i++){
        for(auto j:numbers)
        std::cout<<j<<" ";
        std::cout<<std::endl;
        it=numbers.erase(it);
        it++;
    }
    return 0;
}

OUTPUT:

0 1 2 3 4 5 6 7 8 9 
1 2 3 4 5 6 7 8 9 
1 3 4 5 6 7 8 9 
1 3 5 6 7 8 9 
1 3 5 7 8 9 
1 3 5 7 9 
double free or corruption (out)

Why this process goes just to half of elements. How to delete all list elements one after another step by step? I know I could use numbers.clear(), but I don't need that.

Also, why erasing doesn't go in order? (0 is deleted, then 2, and then 4)?


Solution

  • The issue is with these two lines

    it=numbers.erase(it);
    it++;
    

    The function, list::erase, returns an iterator pointing to the element that followed the last element erased. Here, your code removes the item from the list and sets it to the next element in the list. Then the instruction it++ advances the iterator one more place, hence skipping one item in the list.

    The simple solution is to comment out the it++ line:

    #include <iostream>
    #include <list>
    int main()
    {
        std::list<int>numbers{0,1,2,3,4,5,6,7,8,9};
        auto it=numbers.begin();
        for(int i=0;i<10;i++)
        {
            for(auto j:numbers)
                std::cout<<j<<" ";
            std::cout<<std::endl;
            it=numbers.erase(it);
            //it++;
        }
        return 0;
    }
    

    This gives this output:

    0 1 2 3 4 5 6 7 8 9
    1 2 3 4 5 6 7 8 9
    2 3 4 5 6 7 8 9
    3 4 5 6 7 8 9
    4 5 6 7 8 9
    5 6 7 8 9
    6 7 8 9
    7 8 9
    8 9
    9