You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@stdcxx.apache.org by Geoffrey Winn <ge...@googlemail.com> on 2006/09/06 17:21:26 UTC

Does a list iterator remain valid after removing an element in the list?

I'm investigating an abort that I get from a Tuscant SDO test prgram when
built using stdcxx. I still have some investigation to do however based on
the code I've read I'd like to clarify the following.

If I have a std::<list> and I've created an iterator to examine each item in
the list in turn, if I then use erase to delete one of those items eg

iter = the_list.erase(iter);

does the iterator remain valid?

I'm asking this because the abort occurs in an assert statement within the
implementation of the ++ operator for the iterator.

Thanks in advance.

Geoff.

Re: Does a list iterator remain valid after removing an element in the list?

Posted by Liviu Nicoara <ni...@roguewave.com>.
Iterators and references to the erased elements are invalidated, as per 
23.2.2.3.

- L

Geoffrey Winn wrote:
> I'm investigating an abort that I get from a Tuscant SDO test prgram when
> built using stdcxx. I still have some investigation to do however based on
> the code I've read I'd like to clarify the following.
> 
> If I have a std::<list> and I've created an iterator to examine each 
> item in
> the list in turn, if I then use erase to delete one of those items eg
> 
> iter = the_list.erase(iter);
> 
> does the iterator remain valid?
> 
> I'm asking this because the abort occurs in an assert statement within the
> implementation of the ++ operator for the iterator.
> 
> Thanks in advance.
> 
> Geoff.
> 


Re: Does a list iterator remain valid after removing an element in the list?

Posted by Martin Sebor <se...@roguewave.com>.
Geoffrey Winn wrote:
> That did it. Thank you. We were indeed attempting to increment an iterator
> that was already pointing at the_list.end(). I assume the other
> implementations that we have used just silently leave the iterator
> unchanged.

More likely, they put it in an undefined state. It may not cause
any apparent problems but it is certainly the wrong thing to do.
Other implementations besides stdcxx (including, I believe, the
latest MSVC 8) come with safe iterators that diagnose these types
of problems, but the feature is typically disabled unless the
library is compiled with debugging support (there is a performance
penalty involved in checking for these things).

> Anyway, the whole Tuscany SDO test suite now runs successfully.

I'm glad to hear that!

Martin

> 
> Geoff.
> 
> On 06/09/06, Martin Sebor <se...@roguewave.com> wrote:
> 
>>
>> Geoffrey Winn wrote:
>> > I'm investigating an abort that I get from a Tuscant SDO test prgram
>> when
>> > built using stdcxx. I still have some investigation to do however based
>> on
>> > the code I've read I'd like to clarify the following.
>> >
>> > If I have a std::<list> and I've created an iterator to examine each
>> > item in
>> > the list in turn, if I then use erase to delete one of those items eg
>> >
>> > iter = the_list.erase(iter);
>> >
>> > does the iterator remain valid?
>>
>> No, erase() invalidates all iterator(s) that point to the erased
>> elements. However, the value returned from erase() is a valid,
>> although not necessarily dereferenceable iterator (it may be
>> end()).
>>
>> >
>> > I'm asking this because the abort occurs in an assert statement within
>> the
>> > implementation of the ++ operator for the iterator.
>>
>> That's probably (hopefully :-) our "safe iterator" feature kicking
>> in to let you know that you're trying to increment an iterator past
>> the end of a sequence).
>>
>> FWIW, here's how to safely erase all elements to the end of a list.
>>
>> #include <list>
>>
>> int main ()
>> {
>>      const int a[] = { 1, 2, 3, 4 };
>>      std::list<int> x (a, a + sizeof a / sizeof *a);
>>
>>      std::list<int>::iterator it = x.begin ();
>>      while (it != x.end ())
>>          it = x.erase (it);
>> }
>>
>> Martin
>>
> 


Re: Does a list iterator remain valid after removing an element in the list?

Posted by Geoffrey Winn <ge...@googlemail.com>.
That did it. Thank you. We were indeed attempting to increment an iterator
that was already pointing at the_list.end(). I assume the other
implementations that we have used just silently leave the iterator
unchanged. Anyway, the whole Tuscany SDO test suite now runs successfully.

Geoff.

On 06/09/06, Martin Sebor <se...@roguewave.com> wrote:
>
> Geoffrey Winn wrote:
> > I'm investigating an abort that I get from a Tuscant SDO test prgram
> when
> > built using stdcxx. I still have some investigation to do however based
> on
> > the code I've read I'd like to clarify the following.
> >
> > If I have a std::<list> and I've created an iterator to examine each
> > item in
> > the list in turn, if I then use erase to delete one of those items eg
> >
> > iter = the_list.erase(iter);
> >
> > does the iterator remain valid?
>
> No, erase() invalidates all iterator(s) that point to the erased
> elements. However, the value returned from erase() is a valid,
> although not necessarily dereferenceable iterator (it may be
> end()).
>
> >
> > I'm asking this because the abort occurs in an assert statement within
> the
> > implementation of the ++ operator for the iterator.
>
> That's probably (hopefully :-) our "safe iterator" feature kicking
> in to let you know that you're trying to increment an iterator past
> the end of a sequence).
>
> FWIW, here's how to safely erase all elements to the end of a list.
>
> #include <list>
>
> int main ()
> {
>      const int a[] = { 1, 2, 3, 4 };
>      std::list<int> x (a, a + sizeof a / sizeof *a);
>
>      std::list<int>::iterator it = x.begin ();
>      while (it != x.end ())
>          it = x.erase (it);
> }
>
> Martin
>

Re: Does a list iterator remain valid after removing an element in the list?

Posted by Martin Sebor <se...@roguewave.com>.
Geoffrey Winn wrote:
> I'm investigating an abort that I get from a Tuscant SDO test prgram when
> built using stdcxx. I still have some investigation to do however based on
> the code I've read I'd like to clarify the following.
> 
> If I have a std::<list> and I've created an iterator to examine each 
> item in
> the list in turn, if I then use erase to delete one of those items eg
> 
> iter = the_list.erase(iter);
> 
> does the iterator remain valid?

No, erase() invalidates all iterator(s) that point to the erased
elements. However, the value returned from erase() is a valid,
although not necessarily dereferenceable iterator (it may be
end()).

> 
> I'm asking this because the abort occurs in an assert statement within the
> implementation of the ++ operator for the iterator.

That's probably (hopefully :-) our "safe iterator" feature kicking
in to let you know that you're trying to increment an iterator past
the end of a sequence).

FWIW, here's how to safely erase all elements to the end of a list.

#include <list>

int main ()
{
     const int a[] = { 1, 2, 3, 4 };
     std::list<int> x (a, a + sizeof a / sizeof *a);

     std::list<int>::iterator it = x.begin ();
     while (it != x.end ())
         it = x.erase (it);
}

Martin