unordered_map을 사용하여 char * 키를 정수 값으로 해시하려고했습니다. 커스텀 Functor를 해시하고 char *를 비교 한 후, 정렬되지 않은 맵이 작동하는 것처럼 보였습니다. 그러나 결국 해시가 잘못된 결과를 반환하는 것으로 나타났습니다. 오류를 재현 할 테스트 프로젝트를 만들었습니다. 아래의 코드는 char * 키와 커스텀 펑터를 사용하여 unordered_map을 생성합니다. 그런 다음 1000x 사이클을 실행하고 발생한 모든 해시 오류를 기록합니다. 내 펑터에 문제가 있거나 문제가 unordered_map 내에있는 경우 궁금합니다. 어떤 도움을 주시면 감사하겠습니다. 감사!C++ unordered_map with char * key 예기치 않은 동작이 발생합니다.
#include <cstdlib>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <tr1/unordered_map>
using namespace std;
//These varaibles are just used for printing the 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' was hashed to: '%lu'\n", hashChar, hashVal);
printf("strcmp('%s','%s')='%d' and KeyEqual='%d'\n", c1, c2, cmpVal, cmpRet);
}
int main(int argc, char** argv) {
// Create the 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 the inital hash value of 'apple' to see what it 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 a random character
srand((unsigned int) time(NULL));
char randomChar = (rand() % 26 + 'a');
// Use the hash 1000x times to see if it works properly.
for (int i = 0; i < 1000; i++) {
// Fill the buffer with 'apple'
bzero(buffer, sizeof (buffer));
strcpy(buffer, "apple");
// Try to get the value for 'apple' and report an error if it equals zero.
if (hash_map[buffer] == 0) {
printf("\n****Error: '%s'=0 ****\n", buffer);
printStatus();
}
// Fill the buffer with a random string.
bzero(buffer, sizeof (buffer));
buffer[0] = randomChar;
buffer[1] = '\0';
// Hash the random string.
// ** Taking this line out removes the error. However, based on the functors
// it should be acceptable to reuse a buffer with different content.
hash_map[buffer];
// Update the random character.
randomChar = (rand() % 26 + 'a');
}
printf("done!\n");
return EXIT_SUCCESS;
}
포인터가 문자열이 아닙니다 ... – Pubby
왜 char *가 아닌 문자열입니까? 또한이 태그가 C++ 11이기 때문에 std :: hash를 제안하려고합니다. –
Borgleader
죄송합니다. String을 사용했는데 완벽하게 작동합니다. char *를 사용하고 싶습니다. 나머지 코드는 char *를 모두 사용했기 때문에 사용하고 싶습니다. 지금 당장 나는 왜 unordered_map이 char *와 작동하지 않는지 궁금해합니다. 코드가 올바른 것 같습니다 ... – HobbyDos