c++11 - C++ unordered_map with char* key produces unexpected behavior -
i attempted use unordered_map hash char* key integer value. after writing custom functors hash , compare char*, unordered map appeared work. however, noticed hash return incorrect results. created test project reproduce error. code below creates unordered_map char* key , custom functors. runs 1000x cycles , records hash errors occurred. wondering if there wrong functors, or if problem lies within unordered_map. appreciated. thanks!
#include <cstdlib> #include <stdio.h> #include <string.h> #include <time.h> #include <tr1/unordered_map> using namespace std; //these varaibles used printing status. static const char* c1; static const char* c2; static int cmpret; static int cmpval; static const char* hashchar; static size_t hashval; // character compare functor. struct cmpchar { bool operator()(const char* s1, const char* s2) const { c1 = s1; c2 = s2; cmpval = strcmp(s1, s2); cmpret = (cmpval == 0); return cmpret; } }; // hash functor. struct hashchar { size_t operator()(const char* str) const { hashchar = str; size_t hash = 0; int c; while (c = *str++) hash = c + (hash << 6) + (hash << 16) - hash; hashval = hash; return hash; } }; void printstatus() { printf("'%s' hashed to: '%lu'\n", hashchar, hashval); printf("strcmp('%s','%s')='%d' , keyequal='%d'\n", c1, c2, cmpval, cmpret); } int main(int argc, char** argv) { // create unordered map. tr1::unordered_map<const char*, int, hashchar, cmpchar > hash_map; hash_map["apple"] = 1; hash_map["banana"] = 2; hash_map["orange"] = 3; // grab inital hash value of 'apple' see hashes to. char buffer[256]; bzero(buffer, sizeof (buffer)); strcpy(buffer, "apple"); if (hash_map[buffer] == 1) { printf("first hash: '%s'=1\n", buffer); } printstatus(); // create random character srand((unsigned int) time(null)); char randomchar = (rand() % 26 + 'a'); // use hash 1000x times see if works properly. (int = 0; < 1000; i++) { // fill buffer 'apple' bzero(buffer, sizeof (buffer)); strcpy(buffer, "apple"); // try value 'apple' , report error if equals zero. if (hash_map[buffer] == 0) { printf("\n****error: '%s'=0 ****\n", buffer); printstatus(); } // fill buffer random string. bzero(buffer, sizeof (buffer)); buffer[0] = randomchar; buffer[1] = '\0'; // hash random string. // ** taking line out removes error. however, based on functors // should acceptable reuse buffer different content. hash_map[buffer]; // update random character. randomchar = (rand() % 26 + 'a'); } printf("done!\n"); return exit_success; }
you must careful when using char* in containers, char* won't copied may hope.
by using operator[] of unordered_map used key in map not string want.
operator[] supposed insert key map, copying invoking default constructor (see reference), in case, copy buffer[0].
so afterwards, method cmpchar have strange behaviour, next bytes it'll read in keys can anything.
you not have such problems if using string objetcs.
Comments
Post a Comment