boost::unordered_map непонятки
От: flamin  
Дата: 19.08.11 20:53
Оценка:
Друзья, наскнулся на любопытные грабли в 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;
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.