473,763 Members | 1,382 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Deleting STL list entry - are all iterators invalidated?

Hello

I need to iterate through an STL list container and delete certain
entries in it. I realise if use erase() with the iterator it will
invalidate it but what if I store it beforehand? Ie: is the code below
using a 2nd iterator variable always guaranteed to work or could there
be come internal implementation magic going on inside the list that
could prevent it?

for(iter=objlis t.begin();iter != objlist.end();+ +iter)
{
iter2 = iter;
obj = *iter;
obj->run();
if (obj->destroy_me)
{
objlist.erase(i ter);
delete obj;
iter = iter2;
}
}

Thanks for any help.

B2003

Jan 22 '07 #1
10 2781

Boltar wrote:
for(iter=objlis t.begin();iter != objlist.end();+ +iter)
{
iter2 = iter;
obj = *iter;
obj->run();
if (obj->destroy_me)
{
objlist.erase(i ter);
delete obj;
iter = iter2;
}
}
Sorry , that was some old code I cut and pasted , it should have read:

for(iter=objlis t.begin();iter != objlist.end();)
{
iter2 = iter
iter2++;
obj = *iter;
obj->run();
if (obj->destroy_me)
{
objlist.erase(i ter);
delete obj;
iter = iter2;
}
else iter++;
}

B2003

Jan 22 '07 #2

Boltar wrote:
Hello

I need to iterate through an STL list container and delete certain
entries in it. I realise if use erase() with the iterator it will
invalidate it but what if I store it beforehand? Ie: is the code below
using a 2nd iterator variable always guaranteed to work or could there
be come internal implementation magic going on inside the list that
could prevent it?

for(iter=objlis t.begin();iter != objlist.end();+ +iter)
{
iter2 = iter;
obj = *iter;
obj->run();
if (obj->destroy_me)
{
objlist.erase(i ter);
delete obj;
iter = iter2;
}
}
As long as the program calls std::list's own erase() routine (as the
sample code above does) to remove the element from the list, then only
the iterator that was passed to erase() will be invalidated. In
particular, all other iterators in that same list container remain
valid and will still reference the same list element as before.

Greg

Jan 22 '07 #3
Boltar wrote:
>
Boltar wrote:
>for(iter=objli st.begin();iter != objlist.end();+ +iter)
{
iter2 = iter;
obj = *iter;
obj->run();
if (obj->destroy_me)
{
objlist.erase(i ter);
delete obj;
iter = iter2;
}
}

Sorry , that was some old code I cut and pasted , it should have read:

for(iter=objlis t.begin();iter != objlist.end();)
{
iter2 = iter
iter2++;
obj = *iter;
obj->run();
if (obj->destroy_me)
{
objlist.erase(i ter);
delete obj;
iter = iter2;
}
else iter++;
}
It's not just the iterator that you used with erase() that's invalidated,
but rather all iterators to the erased element. Think about it: iter2
refers to an element that doesn't exist anymore. How could it be valid?
Hint: Have a look at the return value of erase().

Jan 22 '07 #4
Boltar wrote:
Boltar wrote:
for(iter=objlis t.begin();iter != objlist.end();+ +iter)
{
iter2 = iter;
obj = *iter;
obj->run();
if (obj->destroy_me)
{
objlist.erase(i ter);
delete obj;
iter = iter2;
}
}

Sorry , that was some old code I cut and pasted , it should have read:

for(iter=objlis t.begin();iter != objlist.end();)
{
iter2 = iter
iter2++;
obj = *iter;
obj->run();
if (obj->destroy_me)
{
objlist.erase(i ter);
delete obj;
iter = iter2;
}
else iter++;
}
The second iterator is not necessary. Moreover, the loop could be
streamlined a bit:

iter = objlist.begin() ;

while ( iter != objlist.end())
{
(*iter)->run();

if ((*iter)->destroy_me)
{
objlist.erase( iter++ );
continue;
}
iter++;
}

Greg

Jan 22 '07 #5

Rolf Magnus wrote:
Boltar wrote:
for(iter=objlis t.begin();iter != objlist.end();)
{
iter2 = iter
iter2++;
obj = *iter;
obj->run();
if (obj->destroy_me)
{
objlist.erase(i ter);
delete obj;
iter = iter2;
}
else iter++;
}

It's not just the iterator that you used with erase() that's invalidated,
but rather all iterators to the erased element. Think about it: iter2
refers to an element that doesn't exist anymore. How could it be valid?
No, iter2 refers to the element after the one that is erased.
Hint: Have a look at the return value of erase().
Since a std::list's iterators are stable, the iterator that
std::list::eras e() will return is known before erase() is ever called.
Therefore a program can just as easily erase the element at the
iterator's current postion and advance the iterator to the next element
like so:

objlist.erase( iter++ );

Greg

Jan 22 '07 #6

"Boltar" <bo********@yah oo.co.ukwrote in message
news:11******** **************@ 11g2000cwr.goog legroups.com...
>
Boltar wrote:
>for(iter=objli st.begin();iter != objlist.end();+ +iter)
{
iter2 = iter;
obj = *iter;
obj->run();
if (obj->destroy_me)
{
objlist.erase(i ter);
delete obj;
iter = iter2;
}
}

Sorry , that was some old code I cut and pasted , it should have read:

for(iter=objlis t.begin();iter != objlist.end();)
{
iter2 = iter
iter2++;
obj = *iter;
obj->run();
if (obj->destroy_me)
{
objlist.erase(i ter);
delete obj;
iter = iter2;
}
else iter++;
}

B2003
The "normal" way to handle this is like this:

for ( iter=objlist.be gin(); iter != objlist.end(); )
{
obj->run();
if ( obj->destory_me )
iter = objlist.erase( iter );
else
++iter;
}

..erase() returns an iterator just past the one erased.
}
Jan 22 '07 #7
Greg wrote:
>
Rolf Magnus wrote:
>Boltar wrote:
for(iter=objlis t.begin();iter != objlist.end();)
{
iter2 = iter
iter2++;
obj = *iter;
obj->run();
if (obj->destroy_me)
{
objlist.erase(i ter);
delete obj;
iter = iter2;
}
else iter++;
}

It's not just the iterator that you used with erase() that's invalidated,
but rather all iterators to the erased element. Think about it: iter2
refers to an element that doesn't exist anymore. How could it be valid?

No, iter2 refers to the element after the one that is erased.
Ah right. I've seen that the OP corrected his code, but I was still looking
at the first version that didn't have the increment.
>Hint: Have a look at the return value of erase().

Since a std::list's iterators are stable, the iterator that
std::list::eras e() will return is known before erase() is ever called.
Therefore a program can just as easily erase the element at the
iterator's current postion and advance the iterator to the next element
like so:

objlist.erase( iter++ );
Yes. However, I'd still use the return value, like:

iter = objlist.erase(i ter);

Jan 22 '07 #8
"Boltar" <bo********@yah oo.co.ukwrote:
>
for(iter=objlis t.begin();iter != objlist.end();)
{
iter2 = iter
iter2++;
obj = *iter;
obj->run();
if (obj->destroy_me)
{
objlist.erase(i ter);
delete obj;
iter = iter2;
}
else iter++;
}

Something that should have been a member function of std::list:

template < typeanme T >
void remove_if( std::list<T>& li, Fn fn )
{
typename std::list<T>::i terator it = li.begin();
while ( it != li.end() )
if ( fn( *it ) )
li.erase( it++ );
}

Then you can:

bool should_destroy( MyClass* obj ) {
if ( obj->destroy_me ) {
delete obj;
return true;
}
return false;
}

for_each( objlist.begin() , objlist.end(), mem_fun( &MyClass::ru n ) );
remove_if( objlist, &should_dest roy );

Or you can:

bool run_and_check_d estroy( MyClass* obj ) {
obj->run();
if ( obj->destroy_me ) {
delete obj;
return true;
}
return false;
}

remove_if( objlist, &run_and_check_ destroy );
Jan 22 '07 #9

Daniel T. wrote:
"Boltar" <bo********@yah oo.co.ukwrote:

for(iter=objlis t.begin();iter != objlist.end();)
{
iter2 = iter
iter2++;
obj = *iter;
obj->run();
if (obj->destroy_me)
{
objlist.erase(i ter);
delete obj;
iter = iter2;
}
else iter++;
}


Something that should have been a member function of std::list:

template < typeanme T >
void remove_if( std::list<T>& li, Fn fn )
{
typename std::list<T>::i terator it = li.begin();
while ( it != li.end() )
if ( fn( *it ) )
li.erase( it++ );
}
Actually, std::list does have a remove_if() member function.

Greg

Jan 22 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
5633
by: Dave | last post by:
Hello all, After perusing the Standard, I believe it is true to say that once you insert an element into a std::list<>, its location in memory never changes. This makes a std::list<> ideal for storing vertices of an arbitrary n-ary tree where a vertex contain pointers to its parent / children. These parent / child vertices need to stay put if we've got pointers to them somewhere! Am I correct in my assertion?
11
2272
by: William Payne | last post by:
Ok, in my program I have a std::list<Document*>, where Document is one of my own classes. I need to go through this list and check each item if it's ready for deletion. If it's not, skip to next, if it's ready I take steps to delete it. The thing is that the list is part of a gui application and the system removes the Document* from the list during the execution of the loop body. That means I cant use iterators to iterate over the list....
2
2546
by: Mark P | last post by:
What should be the output of the following program? The SGI STL docs say that all iterators remain valid during a splice operation. The dinkumware library reference says that iterators to spliced elts. may be invalidated. I have one system (Linux gcc) which outputs: 0 3 and another (HP aCC) which outputs:
3
9368
by: ngaloppo | last post by:
Hi, compiling a program with the code blurb below causes a runtime error ("Expression: vector iterators incompatible") due to the debug iterators in VC++ 8. The error happens in the ind_len.push_back() call, at the second iteration. I suspect that the iterator has been invalidated, but I can't see how this would be from one iteration to another in this tiny for loop. Could anyone give me more insight? Thanks!
13
6460
by: mahajan.vibhor | last post by:
I have a list of pointers. e.g A* a = new A(); // A is a class stl::list<A*list_a; I am inserting object of class in the after allocating memeory thru new operator. But when i want to erase all elements from the list. my progam crashes. I delete element by using a iterator.
6
2791
by: Jakob Bieling | last post by:
Hi, I want to move an element from a std::list to the end of the same list. To get this done, I thought I'd just do something like: std::list <intlst; lst.push_back (0); lst.push_back (1); lst.push_back (2); lst.splice (lst.end (), lst, lst.begin (), ++ lst.begin ());
2
1614
by: desktop | last post by:
Are there any case where iterators in a std::list gets invalidated besides from the iterator pointing to an element thats deleted? It seems that its only the std::vector that invalidates iterators pointing to elements after a deleted element since its practically just an array.
1
2538
by: subramanian100in | last post by:
Suppose I have vector<intvi; deque<intdi; list<intli; Suppose all of these containers have some elements. Suppose 'v_iter' is an iterator pointing to some element in 'vi'. Suppose 'v_beg' and 'v_end' are valid iterators pointing to some
11
4169
by: Juha Nieminen | last post by:
Assume we have this: std::list<Typelist1(10, 1), list2(20, 2); std::list<Type>::iterator iter = list1.end(); list1.swap(list2); What happens here, according to the standard? 1) 'iter' still points to list1::end(). 2) 'iter' now points to list2::end().
0
9386
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10145
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9938
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9822
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8822
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6642
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5406
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3917
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2793
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.