Друзья, наскнулся на любопытные грабли в unordered_map.
При использовании контейнера с ключами const char * хэш ведет себя некорректно.
А именно — при поиске элемент иногда находится, иногда нет.
(Если запустить приведенный код несколько раз, результаты будут различаться — явное UB непонятного мне происхождения)
#include <stdio.h>
#include <boost/unordered_map.hpp>
struct eqstr
{
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) == 0;
}
};
typedef boost::unordered_map<const char*, int, boost::hash<const char*>, eqstr> TestMap;
int main(int n, char **a)
{
TestMap m;
m[strdup("one")] = 1;
m[strdup("two")] = 2;
m[strdup("three")] = 3;
TestMap::iterator it = m.find("two");
printf("Val: %d\n", (it == m.end() ? -1 : it->second));
return 0;
}
В инете нашел, что виновата хэш функция(каким образом??).
Не поверил, но сделал нормальную функцию — и все заработало!
Объясните мне, почему?
С каких пор качество хэш-функции стало влиять на результаты поиска?
struct str_hash
{
size_t operator()(const char* __s) const
{
unsigned long __h = 0;
for ( ; *__s; ++__s)
__h = 5 * __h + *__s;
return size_t(__h);
}
};
typedef boost::unordered_map<const char*, int, str_hash, eqstr> TestMap;