473,403 Members | 2,338 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,403 software developers and data experts.

std::map - erase+continue

restart:
for (std::map<x,y>::iterator it = m.begin(); it!=m.end(); ++it)
{
if( it->second.isbad() )
{
std::map<x,y>::iterator next = it;
++next;
m.erase(it);
it=next;
// goto restart;
}
}

this does not remove all bad ones... If I insert a "goto restart" it
works...

What am I doing wrong?
--
-Gernot
int main(int argc, char** argv) {printf
("%silto%c%cf%cgl%ssic%ccom%c", "ma", 58, 'g', 64, "ba", 46, 10);}

Jul 23 '05 #1
17 7487

"Gernot Frisch" <Me@Privacy.net>, haber iletisinde şunları
yazdı:39*************@individual.net...
restart:
for (std::map<x,y>::iterator it = m.begin(); it!=m.end(); ++it)
{
if( it->second.isbad() )
{
std::map<x,y>::iterator next = it;
++next;
m.erase(it);
it=next;
// goto restart;
}
}

this does not remove all bad ones... If I insert a "goto restart" it
works...

What am I doing wrong?

When you call "m.erase(it)", next is also invalidated. I guess the following
would fix it.

++next;
x nextkey = next->first;
m.erase(it);
it = m.find(nextkey); // instead of it=next

--
-Gernot
int main(int argc, char** argv) {printf
("%silto%c%cf%cgl%ssic%ccom%c", "ma", 58, 'g', 64, "ba", 46, 10);}

Jul 23 '05 #2

"Aslan Kral" <as**********@yahoo.com>, haber iletisinde şunları
yazdı:39*************@individual.net...

"Gernot Frisch" <Me@Privacy.net>, haber iletisinde şunları
yazdı:39*************@individual.net...
restart:
for (std::map<x,y>::iterator it = m.begin(); it!=m.end(); ++it)
{
if( it->second.isbad() )
{
std::map<x,y>::iterator next = it;
++next;
m.erase(it);
it=next;
// goto restart;
}
}

this does not remove all bad ones... If I insert a "goto restart" it
works...

What am I doing wrong?

When you call "m.erase(it)", next is also invalidated. I guess the

following would fix it.

++next;
x nextkey = next->first;
m.erase(it);
it = m.find(nextkey); // instead of it=next I just realized that it might also be because you increment the iterator
after ++next. Maybe you should do it in a while loop. You see what I mean?

while (it != m.end())
{
if (..)
{
....
++next; // you have already positioned to next
}
else
{
++it; //next
}
}

--
-Gernot
int main(int argc, char** argv) {printf
("%silto%c%cf%cgl%ssic%ccom%c", "ma", 58, 'g', 64, "ba", 46, 10);}


Jul 23 '05 #3
"Aslan Kral" <as**********@yahoo.com> wrote in
news:39*************@individual.net:

"Gernot Frisch" <Me@Privacy.net>, haber iletisinde şunları
yazdı:39*************@individual.net...
restart:
for (std::map<x,y>::iterator it = m.begin(); it!=m.end(); ++it)
{
if( it->second.isbad() )
{
std::map<x,y>::iterator next = it;
++next;
m.erase(it);
it=next;
// goto restart;
}
}

this does not remove all bad ones... If I insert a "goto restart" it
works...

What am I doing wrong?

When you call "m.erase(it)", next is also invalidated. I guess the
following would fix it.


Not in a map it isn't (granted, it is invalidated in a vector...). When
'it' is erased, only iterators to the same element are invalidated.
'next' has already been incremented to the next item (before 'it' has
been erased), so 'next' is safe from being invalidated in this manner.
However, as you point out in your next message, this code is happening
within a for loop, so there are two possible issues that crop up:
1) Adjacent bad items won't get erased, since the second one will be
skipped over.
2) If the last item in the map is bad, undefined behaviour is invoked by
causing the iterator to be incremented past the end() iterator in the
map.

++next;
x nextkey = next->first;
m.erase(it);
it = m.find(nextkey); // instead of it=next


This would probably be less efficient (in terms of time) than the
original code (after correcting for the double increment of the iterator)
as the original code only increments the iterator, this "corrected" code
would require the system to search the entire map again.
Jul 23 '05 #4

"Andre Kostur" <nn******@kostur.net>, haber iletisinde şunları
yazdı:Xn*******************************@207.35.177 .134...
"Aslan Kral" <as**********@yahoo.com> wrote in
news:39*************@individual.net:

"Gernot Frisch" <Me@Privacy.net>, haber iletisinde şunları
yazdı:39*************@individual.net...
restart:
for (std::map<x,y>::iterator it = m.begin(); it!=m.end(); ++it)
{
if( it->second.isbad() )
{
std::map<x,y>::iterator next = it;
++next;
m.erase(it);
it=next;
// goto restart;
}
}

this does not remove all bad ones... If I insert a "goto restart" it
works...

What am I doing wrong?

When you call "m.erase(it)", next is also invalidated. I guess the
following would fix it.


Not in a map it isn't (granted, it is invalidated in a vector...). When
'it' is erased, only iterators to the same element are invalidated.
'next' has already been incremented to the next item (before 'it' has
been erased), so 'next' is safe from being invalidated in this manner.


OK.
However, as you point out in your next message, this code is happening
within a for loop, so there are two possible issues that crop up:
1) Adjacent bad items won't get erased, since the second one will be
skipped over.
2) If the last item in the map is bad, undefined behaviour is invoked by
causing the iterator to be incremented past the end() iterator in the
map.

++next;
x nextkey = next->first;
m.erase(it);
it = m.find(nextkey); // instead of it=next


This would probably be less efficient (in terms of time) than the
original code (after correcting for the double increment of the iterator)
as the original code only increments the iterator, this "corrected" code
would require the system to search the entire map again.


Right. That was because I thought there might a problem there but later I
realized that was not the case.
Jul 23 '05 #5
so... this ins the best: ?

for(std::map<x,y>::iterator it = m.begin(); it!=m.end(); )
{
if(...)
{
std::map<x,y>::iterator next = it;
++next;
m.erase(it);
it=next;
}
else
++it;
}
Jul 23 '05 #6

"Gernot Frisch" <Me@Privacy.net>, haber iletisinde şunları
yazdı:39*************@individual.net...
so... this ins the best: ?

for(std::map<x,y>::iterator it = m.begin(); it!=m.end(); )
{
if(...)
{
std::map<x,y>::iterator next = it;
++next;
m.erase(it);
it=next;
}
else
++it;
}

Maybe. Does it now work the way you want it to? Personally I like "while"
and you seem to prefer "for". No problem.
Jul 23 '05 #7

"Aslan Kral" <as**********@yahoo.com> schrieb im Newsbeitrag
news:39*************@individual.net...

"Gernot Frisch" <Me@Privacy.net>, haber iletisinde şunları
yazdı:39*************@individual.net...
so... this ins the best: ?

for(std::map<x,y>::iterator it = m.begin(); it!=m.end(); )
{
if(...)
{
std::map<x,y>::iterator next = it;
++next;
m.erase(it);
it=next;
}
else
++it;
}

Maybe. Does it now work the way you want it to? Personally I like
"while"
and you seem to prefer "for". No problem.


Yes, it works now. Thank you.
BTW: Does a std::map re-allocate memory for items when
inserting/removing, or does it behave like a std::list?
-Gernot
Jul 23 '05 #8

"Gernot Frisch" <Me@Privacy.net>, haber iletisinde şunları
yazdı:39*************@individual.net...

"Aslan Kral" <as**********@yahoo.com> schrieb im Newsbeitrag
news:39*************@individual.net...

"Gernot Frisch" <Me@Privacy.net>, haber iletisinde şunları
yazdı:39*************@individual.net...
so... this ins the best: ?

for(std::map<x,y>::iterator it = m.begin(); it!=m.end(); )
{
if(...)
{
std::map<x,y>::iterator next = it;
++next;
m.erase(it);
it=next;
}
else
++it;
}

Maybe. Does it now work the way you want it to? Personally I like
"while"
and you seem to prefer "for". No problem.


Yes, it works now. Thank you.
BTW: Does a std::map re-allocate memory for items when
inserting/removing, or does it behave like a std::list?
-Gernot


map/multimap/set/multiset are based on tree structures and they allocate
when you call insert and free when you call erase/clear. So they don't have
a member function like resize() as in list/vector.

Jul 23 '05 #9
"Gernot Frisch" <Me@Privacy.net> wrote in message
news:39*************@individual.net...
for(std::map<x,y>::iterator it = m.begin(); it!=m.end(); )
{
if(...)
{
std::map<x,y>::iterator next = it;
++next;
m.erase(it);
it=next;
}
else
++it;
}


You can simplify it:

for(std::map<x,y>::iterator it = m.begin(); it!=m.end(); )
{
if(...)
m.erase(it++);
else
++it;
}

This version hangs by the thinnest of threads, but it does still work.
Jul 23 '05 #10
This version hangs by the thinnest of threads, but it does still
work.


I do not understand what you mean. :?
Jul 23 '05 #11

"Gernot Frisch" <Me@Privacy.net> schrieb im Newsbeitrag
news:39*************@individual.net...
This version hangs by the thinnest of threads, but it does still
work.


I do not understand what you mean. :?


I _do_ understand now, but I don't understand how it can be working
now ;)

m.erase(it++); is the same as:
m_erase(it); it++;
right?
But after deleting at 'it', I can't '++' it anymore, can I? Does the
std say so?
Jul 23 '05 #12
On Tue, 8 Mar 2005 17:19:42 +0100
"Gernot Frisch" <Me@Privacy.net> wrote:
m.erase(it++); is the same as:
m_erase(it); it++;
right?
But after deleting at 'it', I can't '++' it anymore, can I? Does the
std say so?


No, it is rather like this:

SomeIiterator tmp = it;
++it;
m.erase(tmp);

There is sequence point before erase() call, so it is already
incremented before call starts. Additionally, the erase() call gets old
(i.e. non-incremented) value as an argument.

--
Best regards from
Kamil Burzynski
Jul 23 '05 #13
> map/multimap/set/multiset are based on tree structures and they
allocate when you call insert and free when you call erase/clear. So
they don't have a member function like resize() as in list/vector.


list has a resize?! Oh wait.. resize(), not reserve(). I think the OP was
more concerned as to whether list keeps "dead" nodes around (ie: if you
erase() an element from the list, does the capacity() (assuming list had a
capacity() member) remain constant, or does it go down by 1). No, list
doesn't keep dead nodes around. (Is that mandated by Standard, I'm not
sure).
Jul 23 '05 #14

"Andre Kostur" <nn******@kostur.net> schrieb im Newsbeitrag
news:Xn*******************************@207.35.177. 135...
map/multimap/set/multiset are based on tree structures and they
allocate when you call insert and free when you call erase/clear.
So
they don't have a member function like resize() as in list/vector.


list has a resize?! Oh wait.. resize(), not reserve(). I think the
OP was
more concerned as to whether list keeps "dead" nodes around (ie: if
you
erase() an element from the list, does the capacity() (assuming list
had a
capacity() member) remain constant, or does it go down by 1). No,
list
doesn't keep dead nodes around. (Is that mandated by Standard, I'm
not
sure).


Actually my question was: will pointers to other elements stay when I
remove/insert an element. (vector won't, list will keep pointers
valid)
-Gernot
Jul 23 '05 #15
"Gernot Frisch" <Me@Privacy.net> wrote in news:397qcfF5uq1i4U1
@individual.net:
Actually my question was: will pointers to other elements stay when I
remove/insert an element. (vector won't, list will keep pointers
valid)
-Gernot

Are you sure? In the following code fragment:

list::iterator itr;
list mylist;
for(itr = mylist.begin(); itr != mylist.end(); ++itr) {
// delete the last elemant in the list
}

What happens to the "itr != mylist.end()" test?

BTW, I'm not being smart, I don't know, but suspect
that it is highly compiler dependent.

Jul 23 '05 #16
>> Actually my question was: will pointers to other elements stay when
I
remove/insert an element. (vector won't, list will keep pointers
valid)
-Gernot

Are you sure? In the following code fragment:

list::iterator itr;
list mylist;
for(itr = mylist.begin(); itr != mylist.end(); ++itr) {
// delete the last element in the list
}

What happens to the "itr != mylist.end()" test?

BTW, I'm not being smart, I don't know, but suspect
that it is highly compiler dependent.


What I meant is:

X* pX = &mylist.first();
mylist.push_back(some_X); // Add some more data
mylist.erase(++mylist.begin() ); // Remove the 2nd item

pX -> DoSomething(); // valid if 'mylist' is std::list, propably
invalid it it's std::vector

-Gernot
Jul 23 '05 #17
Peter Gordon <petergo@_deleteme_.netspace.net.au> wrote in
news:Xn**********************************@203.10.1 10.105:
"Gernot Frisch" <Me@Privacy.net> wrote in news:397qcfF5uq1i4U1
@individual.net:
Actually my question was: will pointers to other elements stay when I
remove/insert an element. (vector won't, list will keep pointers
valid)
-Gernot

Are you sure? In the following code fragment:

list::iterator itr;
list mylist;
for(itr = mylist.begin(); itr != mylist.end(); ++itr) {
// delete the last elemant in the list
}

What happens to the "itr != mylist.end()" test?


mylist.end() points to the one-past-the-end element. In this particular
case, it doesn't really matter since .end() is reevaluated every time you
go through the loop.

Nitpick, if you happen to be on the last element when you delete the last
element in the list, this loop will exhibit undefined behaviour since when
you delete the last element, the itr variable becomes an invalidated
iterator. Then you try to increment it, which is undefined behaviour.

Jul 23 '05 #18

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

Similar topics

25
by: Christopher Benson-Manica | last post by:
If you liked the functionality of std::map, but found that you couldn't trust your implementation to handle nonstandard data structures, how would you code a wrapper? I've produced the following:...
14
by: Flzw | last post by:
Well I have a map like this : std::map <string, CObject> ObjectList; I have a function like this : CObject* NewObject( char* Name, CArg* Arg) { std::string key = Name; ObjectList =...
13
by: Peteroid | last post by:
Why does reading a member of a std::map not considered const? For example: class My_Class { int Get_Map_Value( int index ) const // ** error ** not considered const!!! { return m_Map ; //...
20
by: Dilip | last post by:
I understand the C++ standard does not talk about threading. My question here is directed more towards what happens when a STL container is used in a certain way. I'd appreciate any thoughts. I...
25
by: Markus Svilans | last post by:
Hi, There seems to be some functionality missing from the STL. I am iterating through a linked list (std::list) using a reverse iterator and attempting to erase certain items from the list. It...
16
by: Frank Neuhaus | last post by:
Hi I have some std list, I'd like to traverse. During the traversal, I want to conditionally delete some objects. My code for that is like this right now: for (std::list<myStruct>::iterator...
6
by: Evyn | last post by:
Hi, How do I compare 2 maps for identical keys, and if they have identical keys, check if they have identical values? In either case I want to copy ONLY that key value pair to one of two...
6
by: Tobe | last post by:
Hi, Here's an example of something that feels like it should be OK but does in fact produce a segfault on every compiler I've tried (VC2005, g ++ 4.1.2/Linux, g++ 3.4.4/Cygwin). The line marked...
3
by: kernus | last post by:
i am looking for a more elegant/standard way to do this simple operation, however, for now, i just coded this beast. any comments will be grateful, ObserverMap::iterator itr =...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
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,...
0
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...
0
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...
0
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,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.