Rom098
Rom098

Reputation: 2603

Erasing the last element with the reverse_iterator

Recently I found the following in the code I'm maintaining:

for (reverse_iterator rit = base_container::rbegin(); rit != base_container::rend() && 0 < N; N--) 
{
  another_container->push_back(*rit);
  base_container::erase((++rit).base());
}

It tries to remove the last element from a container (std::list in this case) in a loop using the reverse_iterator. The point is that it looks like it should work properly, but it doesn't (some memory corruptions occur due to invalid iterators) and I wonder why? Is there any restriction or rule to not do so?

Thanks.

P.S. To prevent any improvements for the solution, I've already re-written it to make it work. The question is why the code above is not working properly?

Upvotes: 0

Views: 87

Answers (3)

Steephen
Steephen

Reputation: 15824

You need to save the return value of erase() and convert it back to reverse_iterator to avoid iterator invalidation.

for (reverse_iterator rit = base_container::rbegin(); rit != base_container::rend() && 0 < N; N--) 
{
  another_container->push_back(*rit);
  auto it =base_container::erase((++rit).base()); //erase will return an iteraotor
  rit(it);//converting iterator to reverse_iterator.
}

Upvotes: 1

Bathsheba
Bathsheba

Reputation: 234665

rit is invalidated by the erase call.

Upvotes: 1

yizzlez
yizzlez

Reputation: 8805

All iterators after calling erase are invalidated. However, erase returns an iterator that you can use.

Upvotes: 1

Related Questions