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