Archived

This topic is now archived and is closed to further replies.

Erasing an iterator in a loop

This topic is 5808 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

typedef vector[int] nums;
typedef vector[int]::iterator num_handle;

// assume this is filled with random numbers
nums my_numbers;
for (num_handle iter=my_numbers.begin(); iter!=my_numbers.end(); ++iter)
if (*iter == 5)
my_numbers.erase(iter);

This code does not work as well as I intended. In fact it doesn't work at all I know I'm using a vector container in this example but I get the same result using a list container too. I guess erasing the current iterator breaks the pointer chain and when ++iter comes around it points to no where. I need a way to patch that up so I can delete iterators in a loop. Anyone? btw - the [] should be angle brackets I know but, you know... html tags and all... _________________________________________________________________ Drew Sikora A.K.A. Gaiiden ICQ #: 70449988 AOLIM: DarkPylat Blade Edge Software Staff Member, GDNet Public Relations, Game Institute 3-time Contributing author, Game Design Methods , Charles River Media Online column - Design Corner at Pixelate Unnoficial IGDA chat! [polaris.starchat.net -> #igda] NJ IGDA Chapter - NJ developers unite!! [Chapter Home | Chapter Forum] "Real programmers don't work from 9 to 5. If any real programmers are around at 9am it's because they were up all night." -Anon. "It's not the size of the source that matters, it's how you use it" - Self

Share on other sites
If I understand what you are trying to do then I can give you the solution I use.

Rather than (VB/Psuedo code)
  For I = Start to Finish     If condition then Remove(I)  Next

use:
  For I = Finish to Start Step -1     If condition then Remove(I)  Next

Basically you move backwards in the list, so that when you delete an item it only affects the items you have already passed.

[edited by - michalson on January 18, 2003 7:17:51 PM]

Share on other sites
Hmmm, I doubt that would work since you still use the iterator (which would now be invalid) to do the step backwards. Someone posted a good way of doing it (can''t remember who though) like this:

  std::vector<int> my_numbers;for (std::vector<int>::iterator next=my_numbers.begin(),iter=next++ ; iter!=my_numbers.end() ; iter=next++)    if (*iter == 5)        my_numbers.erase(iter);

this keeps next one step ahead, so it will always have a valid iterator.

Joanus D''Mentia
---------------
Surely 100,000 lemmings couldn''t possibly be wrong!!!

Share on other sites
Inserting or removing elements invalidates reference, pointers, and iterators that refer to the following elements. You must use an algorithm to do this. Try this:

std::vector< int >coll;std::vector< int >::iterator pos;std::list< int >mylist;int value;coll.erase(remove(coll.begin(), coll.end(), val), coll.end());list.remove(bind2nd(equal_to< int >(), value));

hope this helps

-----------------------------
"There are ones that say they can and there are those who actually do."

"...u can not learn programming in a class, you have to learn it on your own."

[edited by - cMADsc on January 18, 2003 8:06:32 PM]

Share on other sites
for (num_handle iter=my_numbers.begin(); iter!=my_numbers.end(); )    if (*iter == 5)        iter = my_numbers.erase(iter);    else        ++iter;

[edited by - niyaw on January 18, 2003 8:06:55 PM]

Share on other sites
You can use either the remove or remove_if algorithms to get rid of the elements you don''t want. They return an iterator to the end of the new sequence. You can use that return value with end() of your container to erase the remaining elements, which have already been copied. Check the documentation to see how the algorithms work.

The only problems I can see with this method is that you don''t have the opportunity to call the deconstructor on removed items, since all the algorithm does it overwrite "bad" values with the good ones.

Share on other sites
typedef vector[int] nums;
typedef vector[int]::iterator num_handle

nums my_numbers;
num_handle iter

for (iter=my_numbers.begin();iter!=my_numbers.end();iter++)
{
if(!my_numbers.empty())
{
if (*iter == 5)
{
my_numbers.erase(iter);
}
}
else
{
break;
}
}

Share on other sites
Wow, Gaiiden, a GDNet Staff member asking a question. I thought gods didn''t hang out with the lesser people.

tcache
Contact Me
-----------
AH! MY BRAIN IS GOING TO SELF-DETONATE! -- Yours Truly (Jan, 2003)

Share on other sites

for (int i=my_numbers.size()-1,i>=0;i--)
{
if (my_numbers(i)==5)
my_numbers.erase(my_numbers.begin()+i);
}

I basically always use integers to loop through vectors. Is this a bad practice?

Edit: replaced angle braquets with parenthesis for my_numbers(i) because of html tags...

[edited by - Floating on January 18, 2003 10:56:50 PM]

Share on other sites
quote:
I basically always use integers to loop through vectors. Is this a bad practice?

There are lots of algorithms which solve exactly this sort of problem. If you're still writing your own loops it's likely you're making things deliberately difficult for yourself.

[edited by - petewood on January 19, 2003 2:14:08 AM]

1. 1
2. 2
Rutin
19
3. 3
khawk
15
4. 4
5. 5
A4L
13

• 13
• 26
• 10
• 11
• 44
• Forum Statistics

• Total Topics
633744
• Total Posts
3013652
×