2

I'm trying to use MurmurHash (returning 64 bit hashes on a 64bit comoputer) and have sent it the simple 3 letter string 'yes' as follows

char* charptr = "yes";
cout << MurmurHash64A(charptr, 3, 10);

(where 3 is the length and 10 is the seed) This gives a 64bit hashed response as expected, I can set up more pointers to C strings holding yes and they all return the same hashed value.

But if I try to sending it a C++ string:

string mystring = "yes";
string* strptr = &mystring;
cout << MurmurHash64A(strptr, 3, 10);

...I get a different result to the C string method, what's more if I set up several of these strings in the same way, they all give different results. This suggests to me that strings are maybe not stored in contiguous memory locations, some Googling backed this up. So I then tried to set up a vector in dynamic memory as this was the only way I could think of to force contigous memory. Just like the C++ string method it returned a different result from the C string method and when I set up several they all return a different result from each other. I set them up like follows:

 char yes[3] = {'y', 'e', 's'};
 vector<char> *charvec = new vector<char>;
 void* myvecptr3 = &charvec;
 charvec->reserve(3);
 charvec->push_back(yes[0]);
 charvec->push_back(yes[1]);
 charvec->push_back(yes[2]);

As I understand it my char vector will start at the address the vector is given and fill consecutive bytes with my three characters in the same way as a C string. I am confused why I'm getting different results, any help appreciated? Thanks C

Columbo
  • 2,896
  • 7
  • 44
  • 54
  • 2
    This looks very much like you would benefit from [a good introductory C++ book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – sbi Oct 21 '10 at 11:06

2 Answers2

4

&mystring points at the string object. You want to use mystring.c_str() to get a pointer to a raw character array.

For the vector, you want &(*charvec)[0]. But you probably don't want to use new; you could just do vector<char> charvec; void *myvecptr3 = &charvec[0];.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • Both worked, thanks. Can you advise why &charvec is a different address to &charvec[0], I was expecting them to be the same. Thanks again. – Columbo Oct 21 '10 at 10:41
  • `&charvec` points at the vector object itself, which contains all of its inner workings. `charvec[0]` uses operator overloading to access the first element of the storage owned by the vector. So `&charvec[0]` takes its address. The standard guarantees that the storage owned by a vector will always be contiguous in memory. – Oliver Charlesworth Oct 21 '10 at 10:47
  • 1
    @Columbo: I repeat myself: You do need a good C++ book. ASAP. – sbi Oct 21 '10 at 19:49
2

The reason is that std::string itself stores a pointer to the char array. Try

string mystring = "yes";
cout << MurmurHash64A(mystring.c_str(), 3, 10);

And you would not need to work with char vector indeed.

Keynslug
  • 2,676
  • 1
  • 19
  • 20