'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 1:[1]
it=numbers.erase(it);
it++;
In the first line the list removes the element the iterator points to and returns an iterator pointing at the next element. The old element does no longer exist and the it passed to erase() becomes invalid. That's why you have to use the returned iterator, which points to the next element.
The second line then skips that and the iterator no longer points at the start of the new list.
You are removing every second element from the list: erase, skip, erase, skip, erase, skip, ...
Solution 2:[2]
#include <algorithm>
#include <iostream>
#include <iterator>
#include <list>
template <typename Container>
void print(const Container& container, std::ostream& sout = std::cout) {
std::copy(std::begin(container), std::end(container),
std::ostream_iterator<typename Container::value_type>(sout, " "));
sout << '\n';
}
int main() {
std::list<int> numbers{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
// Note that the update action is skipped
for (auto it = numbers.begin(); it != numbers.end();) {
print(numbers);
it = numbers.erase(it);
}
return 0;
}
This can be done exclusively with iterators. I moved the printing out to its own function. The key here is that the loop declaration is no longer responsible for updating the iterator, as it now happens in the body. Reading about std::list<T>::erase() tells us that the function returns an iterator that points to the element after what was erased. Since we're erasing from the beginning, the act of erasing naturally moves through the whole list.
It's also important to note that the loop has to be done this way. Erasing from the list invalidates all pre-existing iterators of the list. The only valid one now is the iterator returned by the erase() function.
Solution 3:[3]
I suggest you to forget AVD of android studio and start using other AVDs like: NOX or Genymotion which are faster and lighter.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Goswin von Brederlow |
| Solution 2 | |
| Solution 3 | Mohammad Bahadori |
