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

problems with stl map iterators

Hi,

I've some problems with iterators on hashtbales.

My hashtable.h

class HashTable
{
map<int, void*> nhash;
map<int, void*> getNhash();
....
}
----------

My hashtable.cpp:

map<int, void*> HashTable::getNhash() {
return nhash;
}
}
void HashTable::Insert(int ky,void* entr) {
nhash.insert(pair<int, void*>(ky, entr));
}
....

----------

In another class I use this hashtable:

HashTable lNodes;
const std::map<int, void*>::const_iterator begin =
lNodes.getNhash().begin(); const std::map<int, void*>::const_iterator end
= lNodes.getNhash().end(); std::map<int, void*>::const_iterator iter =
begin;

cout << "Size: " << lNodes.getNhash().size() << endl;
while (iter != end)
{
cout << "Key: " << iter->first << endl; ++iter;
}
}
The output:

Size: 3
Key: 0x80a2de0

or

Size: 12
Key: 0x80b8ae8
Key: 0x80b8ee8
Key: 0x80b9170
Key: 0x80b9af0
Key: 0x80bbb68
Key: 0x80bbf68
Key: 0x80bc1f0
Key: 0x80bcb70

There are always some elements missing. Even if the size is 3 just 1
element is printed.
Only with hashtables of size 1 I get the correct output.

What's wrong?

Thank you for your help

Chris
Jul 23 '05 #1
3 3653
Christian Christmann wrote:
Hi,

I've some problems with iterators on hashtbales.

My hashtable.h

class HashTable
{
map<int, void*> nhash;
map<int, void*> getNhash();
...
}
----------

My hashtable.cpp:

map<int, void*> HashTable::getNhash() {
return nhash;
}
}
void HashTable::Insert(int ky,void* entr) {
nhash.insert(pair<int, void*>(ky, entr));
}
...

----------

In another class I use this hashtable:

HashTable lNodes;
const std::map<int, void*>::const_iterator begin =
lNodes.getNhash().begin(); const std::map<int, void*>::const_iterator end
= lNodes.getNhash().end(); std::map<int, void*>::const_iterator iter =
begin;

cout << "Size: " << lNodes.getNhash().size() << endl;
while (iter != end)
{
cout << "Key: " << iter->first << endl; ++iter;
}
}
The output:

Size: 3
Key: 0x80a2de0

or

Size: 12
Key: 0x80b8ae8
Key: 0x80b8ee8
Key: 0x80b9170
Key: 0x80b9af0
Key: 0x80bbb68
Key: 0x80bbf68
Key: 0x80bc1f0
Key: 0x80bcb70

There are always some elements missing. Even if the size is 3 just 1
element is printed.
Only with hashtables of size 1 I get the correct output.

What's wrong?

Thank you for your help

Chris


Please don't multi-post.

I already answered this in the gnu.g++.help newsgroup.

--
Anti-spam address, change each 'X' to '.' to reply directly.
Jul 23 '05 #2
Christian Christmann wrote:
Hi,

I've some problems with iterators on hashtbales.
You're not kidding - although they're maps, not hash tables.
My hashtable.h

class HashTable
{
map<int, void*> nhash;
map<int, void*> getNhash();
...
}
You seem to be returning the nhash member by value here, which is
unusual to say the least. This forces a copy to be made each time
getNhash() is called.

As an aside, I'm assuming this summary is slightly wrong, since both
nhash and getNhash() are private ...
----------

My hashtable.cpp:

map<int, void*> HashTable::getNhash() {
return nhash;
}
I'm just going to remove the extra closing curly bracket, but in
general
it is nice if the posted code actually compiles (since you're not
asking
about a compiler error, at least).
void HashTable::Insert(int ky,void* entr) {
nhash.insert(pair<int, void*>(ky, entr));
}
...

----------

In another class I use this hashtable:

HashTable lNodes;
const std::map<int, void*>::const_iterator begin =
lNodes.getNhash().begin(); const std::map<int, void*>::const_iterator end = lNodes.getNhash().end(); std::map<int, void*>::const_iterator iter = begin;
Mmm, unreadable goo. With permission, I'm going to reformat that so I
have room to hang my comments.

typedef std::map<int,void*>::const_iterator HashIter;

HashIter begin = lNodes.getNhash().begin();
// make a temporary copy of lNodes' std::map, get the begin iterator
// from it, and then throw that copy away. 'begin' is now an
iterator
// into a destroyed temporary copy of a map.

HashIter end = lNodes.getNhash().end();
// make another temporary copy of lNodes' std::map, get the end
// iterator from this copy, and then throw the copy away. 'end' is
// now an iterator into another destroyed temporary copy of a map.

HashIter iter = begin;
// copy of an iterator pointing to a destroyed temporary map
cout << "Size: " << lNodes.getNhash().size() << endl;
This creates the third temporary copy of lNodes.nhash so far, but at
least it should give the right result.
while (iter != end)
{
cout << "Key: " << iter->first << endl; ++iter;
As soon as you dereference an iterator to a deleted map, you're in
'undefined' territory. Simply getting the wrong result is pretty much
the least catastrophic outcome you could hope for.
}
}
The output:
<snip - unsurprisingly wrong output>
There are always some elements missing. Even if the size is 3 just 1
element is printed.
Only with hashtables of size 1 I get the correct output.

What's wrong?
In case you haven't spotted it from the comments above yet, the problem
is that you're making temporary copies of the map and then throwing
them
away. These anonymous temporaries get destroyed as soon as you hit the
';' at the end of the statement where they're created, ie, at the end
of
"... lNodes.getNhash() ... ;"

If you want to get the size of, and iterators into, an HashTable's
nhash
member rather than making a copy and using that, you need getNhash() to
return a reference rather than a value. Change
map<int, void*> getNhash();
map<int, void*> HashTable::getNhash()
{
return nhash;
} to
map<int, void*>& getNhash();
map<int, void*>& HashTable::getNhash()
{
return nhash;
}

and everything will work as you expect. No other changes required.

Especially if you're coming from a language (like Java or Python) that
always passes by reference instead of value [1]: remember that C++
allows you to specify whether your arguments and return values have
reference or value semantics. If you want reference semantics, you
need
to put the '&' in to indicate it.
Thank you for your help
np, hth.
Chris


[1] - ok, Java doesn't always pass by reference, just mostly.

Jul 23 '05 #3
>
Especially if you're coming from a language (like Java or Python) that
always passes by reference instead of value [1]: remember that C++ allows
you to specify whether your arguments and return values have reference or
value semantics. If you want reference semantics, you need
to put the '&' in to indicate it.

Thank you very much for your posting. With your help I could solve
my problem.
np, hth.


Chris

Jul 23 '05 #4

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

Similar topics

4
by: jhonyxxx | last post by:
I have the next programa in C++: #include <iostream.h> // C++ I/O routines #include <list.h> // The STL list class #include<stdio.h> #include <string.h> typedef struct { char nombre; int...
18
by: deancoo | last post by:
I have gotten into the habit of often using copy along with an insert iterator. There are scenarios where I process quite a lot of data this way. Can someone give me a general feel as to how much...
3
by: codefixer | last post by:
Hello, I am trying to understand if ITERATORS are tied to CONTAINERS. I know the difference between 5 different or 6(Trivial, on SGI). But what I fail to understand is how can I declare all 5...
24
by: Lasse Vågsæther Karlsen | last post by:
I need to merge several sources of values into one stream of values. All of the sources are sorted already and I need to retrieve the values from them all in sorted order. In other words: s1 = ...
2
by: ma740988 | last post by:
typedef std::vector < std::complex < double > > complex_vec_type; // option1 int main() { complex_vec_type cc ( 24000 ); complex_vec_type dd ( &cc, &cc ); } versus
9
by: Christian Chrismann | last post by:
Hi, I've a runtime problem with STL vectors. Here is the simplified version of the code: template <class Tclass A { ... private: vector<T*myvector; typename vector<T*>::itarator mIt;
90
by: John Salerno | last post by:
I'm a little confused. Why doesn't s evaluate to True in the first part, but it does in the second? Is the first statement something different? False print 'hi' hi Thanks.
1
by: jmalone | last post by:
I have a python script that I need to freeze on AIX 5.1 (customer has AIX and does not want to install Python). The python script is pretty simple (the only things it imports are sys and socket)....
18
by: desktop | last post by:
1) I have this code: std::list<intmylist; mylist.push_back(1); mylist.push_back(2); mylist.push_back(3); mylist.push_back(4);
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.