Question

I want to create an unordered_map which has a char* as a key and a vector<int> as a value. I learned from previous questions that no hash function for char* is provided by the STL.

I took the first implementation from this site: http://www.cse.yorku.ca/~oz/hash.html

So having my main.cpp file I inserted the following code:

namespace std
{
   template<>
   struct hash<char*>: public std::unary_function<char *, size_t>
   {
      size_t operator()(char * str) const{
      size_t hash = 5381;
      int c;

      while(c = *str++)
        hash = ((hash << 5) + hash) + c; /* hash * 33 + c */

      return hash;

     }
  };
}

Then I created an unordered_map variable:

std::unordered_map<char *, vector<int>> test;

However if I insert the value "temp" twice by doing this:

std::unordered_map<char *, vector<int>> test;
char *t1 = new char[5];
strcpy(t1, "temp");
char *t2 = new char[5];
strcpy(t2, "temp");
vector<int>& ptr = test[t1];
ptr.push_back(0);
vector<int>& ptr2 = test[t2];
ptr2.push_back(1);

the final map instead of having one "temp" key with a vector of size two where each element of the vector is either 0 or 1 it has two keys with the name "temp" and in each key a vector of size 1.

here is detailed picture: enter image description here

how can I avoid this from happening? thank you in advance

Was it helpful?

Solution

It's not a problem with the hashing function, it's a problem with the equality of the char*'s. You're relying upon pointer comparison, and you can see from the debugger watch variables, the pointers of the various "temp" literals have different locations, and are thus not equal.

You need to define an equality functor that actually does the string compare, and use that with the unordered_map.

Or, instead of using char* as your key, use std::string, and avoid this issue altogether.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top