2013-03-27 4 views
1

나는 열쇠로 char*valuevector<int>이있는 unordered_map도를 만들려고합니다. 이전 질문에서 char*에 대한 해시 함수가 STL에 의해 제공되지 않았다는 것을 알게되었습니다. C++ : unordered_map <char *, vector <int>>에 대한 해시 함수가 작동하지 않는 이유는 무엇입니까?

는이 사이트에서 첫 번째 구현을했다 : http://www.cse.yorku.ca/~oz/hash.html

그래서 나는 다음과 같은 코드를 삽입 내 main.cpp 파일을 갖는

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

:

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; 

    } 
    }; 
} 

그럼 내가 unordered_map도 변수를 생성을 그러나이 작업을 수행하여 "temp"값을 두 번 삽입하면

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); 

벡터의 각 요소가 0 또는 1 인 크기가 2 인 벡터가있는 "temp"키 대신 "temp"라는 이름을 가진 두 개의 키가 있으며 각 키에는 enter image description here

가 어떻게 이런 일이 발생하지 않도록 할 수 : 여기

크기 1. 상세한 그림인가? 미리 감사드립니다.

+0

'std :: string'을 사용하지 않는 이유는 무엇입니까? 해시 테이블에 메모리가 누출됩니다. 표준을 사용하여 몇 가지 이유로 – jxh

+0

는 : 문자열은 우리가하지만 경우에, 나에게 아무것도 난 아무것도 변하지 않을 것이라는 느낌 ... – ksm001

답변

3

해싱 기능에는 문제가 없습니다. char*의 동등 함의 문제입니다. 당신은 포인터 비교에 의존하고 있으며 디버거보기 변수에서 볼 수 있습니다. 다양한 "temp"리터럴의 포인터는 다른 위치를 가지므로 동일하지 않습니다.

문자열 비교를 실제로 수행하는 동등 함수기를 정의하고 unordered_map과 함께 사용해야합니다.

또는 char*을 키로 사용하는 대신 std::string을 사용하고이 문제를 방지하십시오.

+0

는 감사가 있지만 숯불 *를 사용하여 변경할 것인지보고 싶다 매우 느린 실행 시간을 준 성능에 대한 이야기, 생성자/소멸자로 인해 char *에 비해 실행 시간이 짧습니다. – ksm001

+2

@ ksm001 : 해시 테이블의 성능은 삽입, 충돌, 검색 및 제거의 혼합에 따라 달라집니다. 일반적인 가정은 검색이 제거 횟수보다 훨씬 많다는 것입니다. 어쨌든 당신의 기억은 결코 자유롭지 않으므로 구현은 속임수입니다. – jxh