Path: csiph.com!x330-a1.tempe.blueboxinc.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!news.glorb.com!news2.glorb.com!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: "Bo Persson" Newsgroups: comp.lang.c++ Subject: Re: list::begin() iterator comportement after push_back operations Date: Sat, 2 Apr 2011 15:37:18 +0200 Lines: 122 Message-ID: <8von4eFt8bU1@mid.individual.net> References: <63a59220-392c-47a7-bbd2-6e42f77e9b70@u12g2000vbf.googlegroups.com> <8voh93Fii1U1@mid.individual.net> X-Trace: individual.net 2AfZVcXDEgYP9njn0vLfhg1gNfh9MAa7IjgJWz29FGMfW3fhdJ Cancel-Lock: sha1:s6gDx/LWBG6/2p47ASrtNqlKi3A= X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.5931 X-RFC2646: Format=Flowed; Original X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5994 X-Antivirus: avast! (VPS 110402-0, 2011-04-02), Outbound message X-Antivirus-Status: Clean Xref: x330-a1.tempe.blueboxinc.net comp.lang.c++:2998 Hizo wrote: > On 2 avr, 13:57, "Bo Persson" wrote: >> Hizo wrote: >>> Hi there, >> >>> I have a problem with the begin iterator of STL Lists. >>> Indeed, if we keep the begin iterator of an empty list when we >>> test it after multiple push_back operations it becomes the end >>> iterator. Here is my code: >> >>> ------------------------------------------- >>> #include >>> using std::cout; >>> using std::endl; >>> using std::boolalpha; >> >>> #include >>> using std::list; >> >>> int main(int argc, char * argv[]) >>> { >>> list l; >>> list::const_iterator it = l.begin(); >>> list::const_reverse_iterator rit = l.rbegin(); >> >>> l.push_back(1); >>> l.push_back(2); >> >>> cout << boolalpha << (it == l.end()) << endl; >>> cout << boolalpha << (rit == l.rend()) << endl; >> >>> return 0; >>> } >>> ------------------------------------------- >> >>> It actually returns: >>> true >>> false >> >>> with gcc version 4.3.4 (Gentoo 4.3.4 p1.0, pie-10.1.5) >> >>> Is it possible to keep in memory the begin iterator of a list (not >>> using reverse iterators) which will really point to the begin of >>> the list after push_back operations on the list (obviously I am >>> not able to use l.begin() after (because it is an initial state >>> in my algorithm and I then update the iterator that pointed to >>> the begin iterator initialy)) >> >>> Thanks for your help. >> >> Short answer: No. >> >> All containers start out with c.begin() == c.end(), as that is one >> way of seeing that the container is empty. >> >> When you add elements to the container, some or all iterators will >> be invalidated. A little different for each container type, but >> definitely the begin() iterator will change when you add an >> element to the start of the container (which of course happens >> when you add to an empty container). >> >> Reverse iterators will not help either, as they will be equally >> invalidated. >> >> Bo Persson > > Alright... > I thought that in lists, it should not be the case since iterators > are not invalidated when adding elements. > > I tried this: > > ------------------------------------------- > #include > using std::cout; > using std::endl; > using std::boolalpha; > > #include > using std::list; > > int main(int argc, char * argv[]) > { > list l; > l.push_back(0); > > list::const_iterator it = l.begin(); > l.pop_back(); > > l.push_back(1); > l.push_back(2); > > cout << *it << endl; > > cout << boolalpha << (it == l.end()) << endl; > > return 0; > } > ------------------------------------------- > > The result (with gcc version 4.3.4 (Gentoo 4.3.4 p1.0, pie-10.1.5)) > is: > 1 > false > > (i.e. the expected result) > > But is it a standard comportement in the STL ? > Can I really rely on this example ? > > Thanks Dereferencing an invalid iterator is undefined behavior, so we can't test for it - anything could happen, like the list allocator reusing the deleted node for one of the new nodes. But we can't rely on that. Bo Persson