Re: Cppcheck Dangerous iterator usage after erase()-method
On 16/09/2012 12:26, Noel Grandin wrote: On Sat, Sep 15, 2012 at 9:13 PM, Markus Mohrhard wrote: Hey, Here are the lines: 178 void SwBlink::FrmDelete( const SwRootFrm* pRoot ) 179 { 180 for( SwBlinkList::iterator it = aList.begin(); it != aList.end(); ) 181 { 182 if( pRoot == (*it).GetRootFrm() ) 183 aList.erase( it ); 184 else 185 ++it; 186 } 187 } I must recognize, I don't understand how can it work above all if we go in the "if" since there's no increment. Any idea? It can't. Line 183 is supposed to be: aList.erase(it++); No, it should be it = aList.erase(it); Once you have called erase(), the iterator becomes invalid, so it must be replaced by the iterator returned by erase(), which returns the next valid position, Except that SwBlinkList inherits from boost::ptr_set, I don't know how iterator works with this class. Some container returns an iterator when you call erase method, some not. Sometimes it depends on if you use C++11 Moreover what kind of things can invalidate iterator still seem hard to remember (see http://cb.nowan.net/blog/2004/12/30/what-will-invalidate-your-iterators/). So I let experts decide :) Julien ___ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice
Re: Cppcheck Dangerous iterator usage after erase()-method
Hey Noel, >> >> It can't. Line 183 is supposed to be: >> >> aList.erase(it++); >> > > No, it should be >it = aList.erase(it); > > Once you have called erase(), the iterator becomes invalid, so it must > be replaced by the iterator returned by erase(), which returns the > next valid position, In a set my version is totally correct. it++ returns the old iterator and then increments it, so we increment before we erase the element and in sets only iterators to the erased element are invalidated. For lists and sets the code I have shown is a common idiom to delete an element. Regards, Markus ___ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice
Re: Cppcheck Dangerous iterator usage after erase()-method
On Sat, Sep 15, 2012 at 9:13 PM, Markus Mohrhard wrote: > Hey, > > >> >> Here are the lines: >> 178 void SwBlink::FrmDelete( const SwRootFrm* pRoot ) >> 179 { >> 180 for( SwBlinkList::iterator it = aList.begin(); it != >> aList.end(); ) >> 181 { >> 182 if( pRoot == (*it).GetRootFrm() ) >> 183 aList.erase( it ); >> 184 else >> 185 ++it; >> 186 } >> 187 } >> >> I must recognize, I don't understand how can it work above all if we go in >> the "if" since there's no increment. >> >> Any idea? > > It can't. Line 183 is supposed to be: > > aList.erase(it++); > No, it should be it = aList.erase(it); Once you have called erase(), the iterator becomes invalid, so it must be replaced by the iterator returned by erase(), which returns the next valid position, ___ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice
Re: Cppcheck Dangerous iterator usage after erase()-method
Thank you Markus. I commited and pushed on master. (see https://gerrit.libreoffice.org/gitweb?p=core.git;a=commitdiff;h=0d40167cec11faee1488397fa323ae4511ac2050) It seems to be only on master so no need to cherry-pick for other branches. Julien -- View this message in context: http://nabble.documentfoundation.org/Cppcheck-Dangerous-iterator-usage-after-erase-method-tp4007715p4007724.html Sent from the Dev mailing list archive at Nabble.com. ___ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice
Re: Cppcheck Dangerous iterator usage after erase()-method
Hey, > > Here are the lines: > 178 void SwBlink::FrmDelete( const SwRootFrm* pRoot ) > 179 { > 180 for( SwBlinkList::iterator it = aList.begin(); it != > aList.end(); ) > 181 { > 182 if( pRoot == (*it).GetRootFrm() ) > 183 aList.erase( it ); > 184 else > 185 ++it; > 186 } > 187 } > > I must recognize, I don't understand how can it work above all if we go in > the "if" since there's no increment. > > Any idea? It can't. Line 183 is supposed to be: aList.erase(it++); Regards, Markus ___ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice
Cppcheck Dangerous iterator usage after erase()-method
Hello, Cppcheck reported this: [sw/source/core/text/blink.cxx:183]: (error) Dangerous iterator usage after erase()-method. Here are the lines: 178 void SwBlink::FrmDelete( const SwRootFrm* pRoot ) 179 { 180 for( SwBlinkList::iterator it = aList.begin(); it != aList.end(); ) 181 { 182 if( pRoot == (*it).GetRootFrm() ) 183 aList.erase( it ); 184 else 185 ++it; 186 } 187 } I must recognize, I don't understand how can it work above all if we go in the "if" since there's no increment. Any idea? Julien -- View this message in context: http://nabble.documentfoundation.org/Cppcheck-Dangerous-iterator-usage-after-erase-method-tp4007715.html Sent from the Dev mailing list archive at Nabble.com. ___ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice