Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Another Question

Reply
Thread Tools

Another Question

 
 
Amit Gupta
Guest
Posts: n/a
 
      01-24-2007
I am puzzled, how the hash_map works. In the following declaration, I
expect it to hash on the character-string, but apparently it hash on
(maybe) the pointer value of string?

Any help is greatly appreciated.


#include <stdio.h>
#include <map>
#include <ext/hash_map>

class A {};

int main()
{
A* a1 = new A();
A* a2 = new A();

__gnu_cxx::hash_map<char*, A*> mapper;
mapper["jan"] = a1;
mapper["feb"] = a2;

char* copy = strdup("jan");
printf("%d\n", mapper[copy]);
// the following works correctly, as in give the right a1 pointer
// printf("%d\n", "jan");
printf("%d\n", mapper["feb"]);

return (0);
}

 
Reply With Quote
 
 
 
 
Amit Gupta
Guest
Posts: n/a
 
      01-24-2007
Ok..I found my mistake. Slightly stupid on my part.

On Jan 24, 1:08 am, "Amit Gupta" <(E-Mail Removed)> wrote:
> I am puzzled, how the hash_map works. In the following declaration, I
> expect it to hash on the character-string, but apparently it hash on
> (maybe) the pointer value of string?
>
> Any help is greatly appreciated.
>
> #include <stdio.h>
> #include <map>
> #include <ext/hash_map>
>
> class A {};
>
> int main()
> {
> A* a1 = new A();
> A* a2 = new A();
>
> __gnu_cxx::hash_map<char*, A*> mapper;
> mapper["jan"] = a1;
> mapper["feb"] = a2;
>
> char* copy = strdup("jan");
> printf("%d\n", mapper[copy]);
> // the following works correctly, as in give the right a1 pointer
> // printf("%d\n", "jan");
> printf("%d\n", mapper["feb"]);
>
> return (0);
>
> }


 
Reply With Quote
 
 
 
 
Ondra Holub
Guest
Posts: n/a
 
      01-24-2007

Amit Gupta napsal:
> I am puzzled, how the hash_map works. In the following declaration, I
> expect it to hash on the character-string, but apparently it hash on
> (maybe) the pointer value of string?
>
> Any help is greatly appreciated.
>
>
> #include <stdio.h>
> #include <map>
> #include <ext/hash_map>
>
> class A {};
>
> int main()
> {
> A* a1 = new A();
> A* a2 = new A();
>
> __gnu_cxx::hash_map<char*, A*> mapper;
> mapper["jan"] = a1;
> mapper["feb"] = a2;
>
> char* copy = strdup("jan");
> printf("%d\n", mapper[copy]);
> // the following works correctly, as in give the right a1 pointer
> // printf("%d\n", "jan");
> printf("%d\n", mapper["feb"]);
>
> return (0);
> }


It is not good idea to use const char* (or char*) as key for map
containers (and I think for hash_map too), because it really uses
pointers as key value.

You have no guarantee, that all equal text literals will be merged to
one place in memory. So on some compilers

mapper["x"] = 1;
mapper["x"] = 2;

Will add 2 different values into mapper, on some will it add value 1
which is overwritten with value 2.

Use std::string instead and you do not have problem.

 
Reply With Quote
 
Gayan_on@yahoo.com
Guest
Posts: n/a
 
      01-24-2007
You have a error in command on #include <ext/hash_map> please tell
what is it.


On Jan 24, 4:22 pm, "Ondra Holub" <(E-Mail Removed)> wrote:
> Amit Gupta napsal:
>
>
>
>
>
> > I am puzzled, how the hash_map works. In the following declaration, I
> > expect it to hash on the character-string, but apparently it hash on
> > (maybe) the pointer value of string?

>
> > Any help is greatly appreciated.

>
> > #include <stdio.h>
> > #include <map>
> > #include <ext/hash_map>

>
> > class A {};

>
> > int main()
> > {
> > A* a1 = new A();
> > A* a2 = new A();

>
> > __gnu_cxx::hash_map<char*, A*> mapper;
> > mapper["jan"] = a1;
> > mapper["feb"] = a2;

>
> > char* copy = strdup("jan");
> > printf("%d\n", mapper[copy]);
> > // the following works correctly, as in give the right a1 pointer
> > // printf("%d\n", "jan");
> > printf("%d\n", mapper["feb"]);

>
> > return (0);
> > }It is not good idea to use const char* (or char*) as key for map

> containers (and I think for hash_map too), because it really uses
> pointers as key value.
>
> You have no guarantee, that all equal text literals will be merged to
> one place in memory. So on some compilers
>
> mapper["x"] = 1;
> mapper["x"] = 2;
>
> Will add 2 different values into mapper, on some will it add value 1
> which is overwritten with value 2.
>
> Use std::string instead and you do not have problem.- Hide quoted text -- Show quoted text -


 
Reply With Quote
 
Ondra Holub
Guest
Posts: n/a
 
      01-24-2007

Ondra Holub napsal:
> Amit Gupta napsal:
> > I am puzzled, how the hash_map works. In the following declaration, I
> > expect it to hash on the character-string, but apparently it hash on
> > (maybe) the pointer value of string?
> >
> > Any help is greatly appreciated.
> >
> >
> > #include <stdio.h>
> > #include <map>
> > #include <ext/hash_map>
> >
> > class A {};
> >
> > int main()
> > {
> > A* a1 = new A();
> > A* a2 = new A();
> >
> > __gnu_cxx::hash_map<char*, A*> mapper;
> > mapper["jan"] = a1;
> > mapper["feb"] = a2;
> >
> > char* copy = strdup("jan");
> > printf("%d\n", mapper[copy]);
> > // the following works correctly, as in give the right a1 pointer
> > // printf("%d\n", "jan");
> > printf("%d\n", mapper["feb"]);
> >
> > return (0);
> > }

>
> It is not good idea to use const char* (or char*) as key for map
> containers (and I think for hash_map too), because it really uses
> pointers as key value.
>
> You have no guarantee, that all equal text literals will be merged to
> one place in memory. So on some compilers
>
> mapper["x"] = 1;
> mapper["x"] = 2;
>
> Will add 2 different values into mapper, on some will it add value 1
> which is overwritten with value 2.
>
> Use std::string instead and you do not have problem.


If you really need to use const char* as key value, you have to specify
custom way to compare key values as 3rd parameter:

struct strCmp
{
bool operator()( const char* s1, const char* s2 ) const
{
return strcmp(s1, s2) < 0;
}
};

typedef
std::map<const char*, int, strCmp> M;

 
Reply With Quote
 
Ondra Holub
Guest
Posts: n/a
 
      01-24-2007

http://www.velocityreviews.com/forums/(E-Mail Removed) napsal:
> You have a error in command on #include <ext/hash_map> please tell
> what is it.
>
>
> On Jan 24, 4:22 pm, "Ondra Holub" <(E-Mail Removed)> wrote:
> > Amit Gupta napsal:
> >
> > > I am puzzled, how the hash_map works. In the following declaration, I
> > > expect it to hash on the character-string, but apparently it hash on
> > > (maybe) the pointer value of string?

> >


I think your reaction should be on Amit Gupta's message. hash_map is
not part of standard C++ library. But I thought that the same problem
may arise with std::map too, so that's why I explained it on std::map.
You can test it on following code (see line with !!!):

#include <iostream>
#include <cstring>
#include <map>

struct strCmp
{
bool operator()( const char* s1, const char* s2 ) const
{
return strcmp(s1, s2) < 0;
}
};

int main()
{
typedef
std::map<const char*, int, strCmp> M1;

M1 m1;
m1["a"] = 1;
m1["a"] = 2;

for (M1::const_iterator it = m1.begin(); it != m1.end(); ++it)
std::cout << "m[" << it->first << "] = " << it->second << '\n';

std::cout << '\n';

typedef
std::map<const char*, int> M2;

M2 m2;
m2["a"] = 1;
m2["a"] = 2; //!!! here is undefined, whether it overwrites value 1
or creates new one

for (M2::const_iterator it = m2.begin(); it != m2.end(); ++it)
std::cout << "m[" << it->first << "] = " << it->second << '\n';
}

 
Reply With Quote
 
Default User
Guest
Posts: n/a
 
      01-24-2007
(E-Mail Removed) wrote:

> You have a error in command on #include <ext/hash_map> please tell
> what is it.


Please don't top-post. Your replies belong following or interspersed
with properly trimmed quotes. See the majority of other posts in the
newsgroup, or the group FAQ list:
<http://www.parashift.com/c++-faq-lite/how-to-post.html>
 
Reply With Quote
 
Amit Gupta
Guest
Posts: n/a
 
      01-25-2007
I agree. The problem here is the comparison functor should be provided
to the map template (and perhaps hasher too).

In your example, it is not quite *undefined* what will happen, instead
it is unpredictable. If both calls to m2["a"] uses same pointer value
(which it probably will), the data will get over-written.

Instead, if you do "m2[strdup("a")] = 2;, it will create a new entry.


> M2 m2;
> m2["a"] = 1;
> m2["a"] = 2; //!!! here is undefined, whether it overwrites value 1
> or creates new one
>
> for (M2::const_iterator it = m2.begin(); it != m2.end(); ++it)
> std::cout << "m[" << it->first << "] = " << it->second << '\n';
>
> }


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Another basic question: How to call and show one Web Form from another Web Form? Rob R. Ainscough ASP .Net Web Controls 3 06-14-2005 03:56 PM
another newbie question from another newbie.... Lee UK VOIP 4 05-17-2005 04:10 PM
Renaming a project with another project as the starting point? In another solution Maziar Aflatoun ASP .Net 1 01-22-2005 12:49 AM
How to access: a page from a User control, and another User controlfrom another one? qwerty ASP .Net 3 09-30-2004 05:32 PM
Access a control inside an usercontrol from another control inside another usercontrol nail ASP .Net 0 09-15-2004 03:55 PM



Advertisments