473,387 Members | 1,517 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,387 software developers and data experts.

std::map iterator and clearing

I have been learning about STL's map class. I see that I can clear a
hashmap by useing the method clear, however I decided to try to clear
the hash with a for loop. Since erase can take an iterator as a
position I thought I could do something like this:

hashTable::iterator i;

for (i = phoneBook.begin(); i != phoneBook.end(); i++)
{
cout << i->first << endl;
phoneBook.erase(i);
}

I get an access violation, I think the reason is that the condition is
never false , and thus the loop continues to now access memory beyond
phoneBook. But I cannot see why. If i comment out the erase line I am
ok, but what I am trying to do is to clear the phoneBook. Without
useing clear method.

Could somebody give me a hint, is it true the condition is never false?
What could possibly be causeing that.

Jul 23 '05 #1
8 6539
Kelly Mandrake wrote:
I have been learning about STL's map class. I see that I can clear a
hashmap by useing the method clear, however I decided to try to clear
hashmap is not a standard class.
the hash with a for loop. Since erase can take an iterator as a
position I thought I could do something like this:

hashTable::iterator i;

for (i = phoneBook.begin(); i != phoneBook.end(); i++)
{
cout << i->first << endl;
phoneBook.erase(i);
At this point, i is an invalid iterator. I suspect the correct code
should be:

for (i = phoneBook.begin(); i != phoneBook.end() ; )
{
cout << i->first.endl;
i = phoneBook.erase(i); // guess, don't know what
// hashmap::erase returns
} }

I get an access violation, I think the reason is that the condition is
never false , and thus the loop continues to now access memory beyond
phoneBook. But I cannot see why. If i comment out the erase line I am
ok, but what I am trying to do is to clear the phoneBook. Without
useing clear method.

Could somebody give me a hint, is it true the condition is never false?
What could possibly be causeing that.

Jul 23 '05 #2
red floyd wrote:
Kelly Mandrake wrote:
I have been learning about STL's map class. I see that I can clear a
hashmap by useing the method clear, however I decided to try to clear

hashmap is not a standard class.
the hash with a for loop. Since erase can take an iterator as a
position I thought I could do something like this:

hashTable::iterator i;

for (i = phoneBook.begin(); i != phoneBook.end(); i++)
{
cout << i->first << endl;
phoneBook.erase(i);

At this point, i is an invalid iterator. I suspect the correct code


Sorry, meant to say, i is invalid, so i++ has no meaning.
should be:

for (i = phoneBook.begin(); i != phoneBook.end() ; )
{
cout << i->first.endl;
i = phoneBook.erase(i); // guess, don't know what
// hashmap::erase returns
}
}

I get an access violation, I think the reason is that the condition is
never false , and thus the loop continues to now access memory beyond
phoneBook. But I cannot see why. If i comment out the erase line I am
ok, but what I am trying to do is to clear the phoneBook. Without
useing clear method.

Could somebody give me a hint, is it true the condition is never false?
What could possibly be causeing that.

Jul 23 '05 #3
sorry, i forgot to say i typedefed hashmap like so

typedef map<string, string> hashTable;

unfortunately also when I try i = phoneBook.erase(i) I get no match for
'operator=' in 'i = (&phoneBook)->......

I think the reason is my implementation of STL returns void from erase,
this is my guess after reading an article about the difernt
implementations of STL. Actualy this code I wrote was a test because
im trying to port code writen for msvc.

is the reason i is invalid because i didnt mention my typedef? Because
it will compile if i comment out the line phoneBook.erase(i); it will
work fine I think i++ is ok in my case, but what exactly hapens when
erase is called? The documentation i found on microsft does not seem
to explain this.

Jul 23 '05 #4
Kelly Mandrake wrote:
sorry, i forgot to say i typedefed hashmap like so

typedef map<string, string> hashTable;

unfortunately also when I try i = phoneBook.erase(i) I get no match for
'operator=' in 'i = (&phoneBook)->......

I think the reason is my implementation of STL returns void from erase,
this is my guess after reading an article about the difernt
implementations of STL. Actualy this code I wrote was a test because
im trying to port code writen for msvc.

is the reason i is invalid because i didnt mention my typedef? Because
it will compile if i comment out the line phoneBook.erase(i); it will
work fine I think i++ is ok in my case, but what exactly hapens when
erase is called? The documentation i found on microsft does not seem
to explain this.


You're right. std::map::erase doesn't return anything, probably because
the tree gets re-sorted/rebalanced after deleting, and iterator ordering
may no longer make sense.

If you're just ripping through in order, you might want to try:

while (!phoneBook.empty())
{
i = phoneBook.begin();
// do stuff with i
phoneBook.erase(i);
}

Or, alternatively

std::for_each(phoneBook.begin(),
phoneBook.end(),
DoSomethingWithPhoneBookFunctor());
phoneBook.clear();
Jul 23 '05 #5
Well that worked, and It never ocured to me to test for empty. So
every time i call erase the tree is resorted, very interesting. Still
trying to figure out things I looked up the documentation for end and i
was suprized, one reference mentioned that if the map is empty then
end() is the same as begin(), but when I tested for begin I got same
results. But it makes sence now you mention the tree gets resorted, so
end gets confused.

Both your examples worked thank you for these. I decided to try one on
my own after reviewing yours and came up with

for (hashTable::iterator i = phoneBook.begin(); !phoneBook.empty();
i++)
{
cout << i->first << endl;
phoneBook.erase(i);
}

Jul 23 '05 #6
Kelly Mandrake wrote:
Well that worked, and It never ocured to me to test for empty. So
every time i call erase the tree is resorted, very interesting. Still
trying to figure out things I looked up the documentation for end and i
was suprized, one reference mentioned that if the map is empty then
end() is the same as begin(), but when I tested for begin I got same
results. But it makes sence now you mention the tree gets resorted, so
end gets confused.

Both your examples worked thank you for these. I decided to try one on
my own after reviewing yours and came up with

for (hashTable::iterator i = phoneBook.begin(); !phoneBook.empty();
i++)
{
cout << i->first << endl;
phoneBook.erase(i);
}


Still not good. After the phoneBook.erase(i) statement, i is not longer
a valid iterator, and the i++ in the loop is UB.

Also, when dealing with iterators, it's generally considered better form
to use the preincrement (++i) form unless there's a really good reason
for postincrement.
Jul 23 '05 #7
It did compile and execute ok for me though, all three seem to work.
May I ask which STL you are useing, I am useing g++ 3.4 with stl that
came with it. I will remember to use the preincrement from now on,
thanks for this.

Jul 23 '05 #8

red floyd wrote:
Kelly Mandrake wrote:
I thought I could do something like this:

hashTable::iterator i;

for (i = phoneBook.begin(); i != phoneBook.end(); i++)
{
cout << i->first << endl;
phoneBook.erase(i);


At this point, i is an invalid iterator. I suspect the correct code
should be:

for (i = phoneBook.begin(); i != phoneBook.end() ; )
{
cout << i->first.endl;
i = phoneBook.erase(i); // guess, don't know what
// hashmap::erase returns
}


Basic idea is OK, but this depends on the return type of erase.
This is one of the few cases where post-increment
is useful (++i is at least as efficient and often more)

for (i = phoneBook.begin(); i != phoneBook.end() ; )
{
cout << i->first.endl;
phoneBook.erase(i++);
}
the point is that i++ returns the old value as a temporary. Usually
that's totally redundant, but in this case it's very useful. Once
erased, the temporary iterator is destroyed.

This will also work if empty, because an empty container has
begin==end (another reason why STL uses half-open ranges).

(Note: hashmap is not a std:: class yet, so what you've got may
in fact invalidate all iterators on an erase. So, RTFM )

HTH,
Michiel Salters

Jul 23 '05 #9

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

Similar topics

5
by: Christopher | last post by:
I am having problems iterating through the sequence of objects stored in my std::map I want to call a function from the "value" object in the map. Here is my snippet: typedef std::map<SOCKET,...
24
by: Duane Hebert | last post by:
2 questions: Given a map defined as std::map<int,string> stringmap; //How do you access the data_type (string) via an iterator? std::string spoo("doh");
5
by: Angus Leeming | last post by:
Dinkumware's online STL reference http://tinyurl.com/3es52 declares std::map's overloaded erase member functions to have the interface: map::erase iterator erase(iterator where); iterator...
17
by: Gernot Frisch | last post by:
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;
19
by: Erik Wikström | last post by:
First of all, forgive me if this is the wrong place to ask this question, if it's a stupid question (it's my second week with C++), or if this is answered some place else (I've searched but not...
1
by: Avery Fong | last post by:
The following program will result in a compile error when building under Debug but will compile under Release. Why does is work under Release mode but not under Debug This program is developed...
13
by: kamaraj80 | last post by:
Hi I am using the std:: map as following. typedef struct _SeatRowCols { long nSeatRow; unsigned char ucSeatLetter; }SeatRowCols; typedef struct _NetData
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...
8
by: mveygman | last post by:
Hi, I am writing code that is using std::map and having a bit of an issue with its performance. It appears that the std::map is significantly slower searching for an element then a sequential...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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
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
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
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...
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
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

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.