1

This time I'm able to show a complete code:

#include <unordered_map>
#include <iostream>
#include <stdlib.h>

using namespace std;

bool mystrcmp(const char *s1, const char *s2) {
        int i = 0;
        do {
                if(s1[i] != s2[i])
                        return false;
        } while(s1[i++] != '\0');
        return true;
}

struct eqstr
{
  bool operator()(const char* s1, const char* s2) const
  {
    return mystrcmp(s1, s2);
  }
};


int main(void) {
    char buffer[5] = {'h', 'e', 'd', 'e', '\0'};
    unordered_map<char *, int , hash<char *> , eqstr> int_from_symbols;
    int_from_symbols["hede"] = 1;
    int_from_symbols["hodo"] = 2;
    unordered_map<char *, int , hash<char *> , eqstr>::const_iterator it = int_from_symbols.find(buffer);
    eqstr myeq;
    if(myeq("hede",buffer))
        fprintf(stderr, "no problem here\n");
    if(it == int_from_symbols.end())
        fprintf(stderr, "dammit\n");
    else fprintf(stderr, "%d\n", int_from_symbols[buffer]);
    return 0;
}

This outputs:

no problem here
dammit

Any idea what's going on?

Thanks in advance,,
Onur

2 Answers 2

2

The problem is that hash<char *> does not do what you want. It is not specialized to actually hash the 'string' but is simply returning the pointer as the hash.

Add this to your code and it will start working (although the hash function is not production quality and is for demonstration only):

namespace std
{
    template<>
    struct hash<char *> : public std::unary_function<char *, size_t>
    {
        size_t operator()(char* str) const
        { 
            size_t h = 0;
            for (; *str; ++str)
                h += *str;
            return h;
        }
    };
}
Sign up to request clarification or add additional context in comments.

6 Comments

I don't think that globally specializing hash<char*> for this is a good idea - among other things, this might make it very easy to break ODR. Why not just define a custom functor, and pass that as a template argument to unordered_map, as usual?
Check your <functional> header for the hash<string> specialization.
This is really annoying. I implemented other hash functions which encodes the structures as strings and used hash<char *> to hash those. Those hash functions worked correctly, if hash<char *> works incorrectly, why other ones worked correctly?
OK, you are right. hash<char *> barely returns the pointer. Thank you for the answer, however, I need a good quality hash function for strings. Can you recommend me one?
The namespace std is reserved. Never, ever drop anything of your own into it.
|
1

a review of a few hash function algoirthms for 'char *' here:

http://www.cse.yorku.ca/~oz/hash.html

the sum of ascii codes mentioned above is not the best as the author of the comment says.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.