[STL] hash_map problem

G

gibffe

Hello

I have a big problem with hash_map in stl.

I'm trying to create hash_map<const char *, char *> map
to keep key => val pairs as 4 byte C "strings".

Everything is ok when i do let's say
my_hash["abc"] = "efg";
my_hash["aa"] = "bb";
and then
for (it = my_hash.begin(); it != my_hash.end(); ++it)
printf("%s %s\n", it->first, it->second);
it will print 2 entries


The problem starts when i try to push values to my_hash that
i read from a file. Here's a bit of code:


for (i = 0; i < N2; i++)
{
fread_unlocked(mro1, sizeof(char), 4, stdin);
fread_unlocked(mro2, sizeof(char), 4, stdin);

m_hash[mro1] = (char *) malloc(4*sizeof(char));
memcpy(m_hash[mro1], mro2, 4);
/*
or like this:

m_hash[mro1] = mro2

*/
}

mro1 and mro2 are 4*sizeof(char) bytes malloced vectors


for (it = my_hash.begin(); it != my_hash.end(); ++it)
printf("%s %s\n", it->first, it->second);

will print only one, last entry i read from file. I figured out that it no
longer keeps "strings" as keys but pointers. Can someone tell me how to make
it work like my_hash["dljfj"] = "dlkfjkjdf"; ?

gibffe
 
G

Guest

I'm trying to create hash_map<const char *, char *> map
to keep key => val pairs as 4 byte C "strings".

You are not taking advantage of std::string and struggling with C-style
strings.
Everything is ok when i do let's say
my_hash["abc"] = "efg";
my_hash["aa"] = "bb";
and then
for (it = my_hash.begin(); it != my_hash.end(); ++it)
printf("%s %s\n", it->first, it->second);
it will print 2 entries


The problem starts when i try to push values to my_hash that
i read from a file. Here's a bit of code:


for (i = 0; i < N2; i++)
{
fread_unlocked(mro1, sizeof(char), 4, stdin);
fread_unlocked(mro2, sizeof(char), 4, stdin);

m_hash[mro1] = (char *) malloc(4*sizeof(char));

So you are using the same key (the value of mro1, which is a memory address)
for everything you read. You are overwriting the old value each time you do
this.

Since you don't free the previously malloced 4 bytes, you also leak memory
here.
memcpy(m_hash[mro1], mro2, 4);
/*
or like this:

m_hash[mro1] = mro2

If you did that, you would not leak memory, but still keep one key/value
pair (mro1/mro2) in the container.
*/
}

mro1 and mro2 are 4*sizeof(char) bytes malloced vectors

Since you don't malloc mro1 per key, your key is the same for everything you
read.
for (it = my_hash.begin(); it != my_hash.end(); ++it)
printf("%s %s\n", it->first, it->second);

will print only one, last entry i read from file. I figured out that it no
longer keeps "strings" as keys but pointers. Can someone tell me how to make
it work like my_hash["dljfj"] = "dlkfjkjdf"; ?

Use std::string, not 'char *':

#include <string>
/* ... */
typedef hash_map<std::string, std::string> MyMap;

MyMap m_hash;
m_hash["dljfj"] = "dlkfjkjdf";

Ali
 
J

John Harrison

Use std::string, not 'char *':

#include <string>
/* ... */
typedef hash_map<std::string, std::string> MyMap;

MyMap m_hash;
m_hash["dljfj"] = "dlkfjkjdf";

Obviously this is the correct advice. But the thing to add is that some
implementations of hash_map do not have a hash function defined for
std::string. Therefore the OP might need to do add that themselves. Since
hash_map is non-standard the way to do that will vary, consult your
documentation. The other option would be to switch to std::map (and use
std::string of course).

john
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,240
Members
46,830
Latest member
HeleneMull

Latest Threads

Top