Why does the following code crash? And what should I do when I am iterating via reverse iterator. How do I erase individual elements then?
deque q;
q.push_back(4);
q.push_back(41);
q.push_back(14);
for (auto it = q.begin(); it != q.end();) {
auto current = it;
q.erase(current);
it++;
}
- Why does the following code crash ? How do I erase individual elements then ?
std::deque::erase
invalidates iterators.
All iterators and references are invalidated, unless the erased elements are at the end or the beginning of the container, in which case only the iterators and references to the erased elements are invalidated.
The past-the-end iterator is also invalidated unless the erased elements are at the beginning of the container and the last element is not erased.
In your code, the iterators to the element to be erased (i.e. it
and current
) will become invalid after q.erase(current)
, then it++
will lead to UB.
You could make use of the return value of std::deque::erase
Iterator following the last removed element. If the iterator pos refers to the last element, the
end()
iterator is returned.
for (auto it = q.begin(); it!=q.end(); )
{
it = q.erase(it);
}
- And what should I do if I am iterating via reverse iterator.
Because std::deque::erase
doesn't accept reverse_iterator
as parameters, you need to use base()
to convert it to normal iterator (pay attention to the position conversion). Such as
for (auto it = q.rbegin(); it!=q.rend(); )
{
it = std::make_reverse_iterator(q.erase((++it).base()));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With