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 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
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
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().
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
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
"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.
}
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);
"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 );
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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?
|
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....
|
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:
|
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!
|
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.
| |
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 ());
|
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.
|
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
|
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().
|
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,...
|
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...
| |
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,...
|
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...
|
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...
|
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();...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
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
| |
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...
| |