I have following code:
#include <cstring>
#include <boost/functional/hash.hpp>
#include <iostream>
int main(int argc, char **argv)
{
const char *str1 = "teststring";
// copy string
size_t len = strlen(str1);
char *str2 = new char[len+1];
strcpy(str2, str1);
// hash strings
std::cout << "str1: " << str1 << "; " << boost::hash<const char*>()(str1) << std::endl;
std::cout << "str2: " << str2 << "; " << boost::hash<const char*>()(str2) << std::endl;
delete[] str2;
return 0;
}
I always get the same hash for str1 (as expected). But str2 differs - in fact it returns a different hash every time I run the programm.
Can someone explain why?
As Linuxios suggested, it's hashing the pointer value, not the string. I did a quick test with this code:
char str1[] = "teststring";
std::cout << "str1: " << str1 << "; " << boost::hash<const char*>()(str1) << std::endl;
str1[3] = 'x';
std::cout << "str1: " << str1 << "; " << boost::hash<const char*>()(str1) << std::endl;
And here's the output. Note that the string is different but since the pointer is the same the hash matches.
str1: teststring; 158326806782903
str1: tesxstring; 158326806782903
The only change you need to make is to tell boost it's hashing a std::string
and it will give you matching hashes. Your underlying data can remain char*
.
std::cout << "str1: " << str1 << "; " << boost::hash<std::string>()(str1) << std::endl;
std::cout << "str2: " << str2 << "; " << boost::hash<std::string>()(str2) << std::endl;
Result:
str1: teststring; 10813257313199645213
str2: teststring; 10813257313199645213
If you actually want the hash of the string not the pointer then you can either use the boost::hash_range
function or a custom loop using hash_combine and write your own hash function object. boost::hash<std::basic_string<...> >
does hashes using hash_range
, with has_range
in turn using hash_combine
.
eg something like this:
struct CStringHash : public std::unary_function<char const*, std::size_t> {
std::size_t operator()(char const* v) const {
std::size_t seed = 0;
for (; *v; ++v) {
boost::hash_combine(seed, *v);
}
return seed;
}
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.