1

I am confused with what parameter should I provide for the MurmurHash3_x86_128(). The murmurhash3 code can be found https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp. Method definition is given below.

void MurmurHash3_x86_128 ( const void * key, const int len,
                       uint32_t seed, void * out )

I have passed the following values in the above method but my compiler is giving me segmentation fault. What am i doing wrong ?

int main()
{
    uint64_t seed = 1;
    uint64_t *hash_otpt;
    const char *key = "hi";
    MurmurHash3_x64_128(key, (uint64_t)strlen(key), seed, hash_otpt);
    cout << "hashed" << hash_otpt << endl;
    return 0;
}
Ami Tavory
  • 74,578
  • 11
  • 141
  • 185
rombi
  • 199
  • 3
  • 22
  • At least you should allocate memory for `hash_otpt`. Currently you are passing invalid pointer to the function – mvidelgauz Aug 19 '16 at 11:15

3 Answers3

4

This function put its hash in 128 bits of memory.

What your are doing is passing a pointer, that is not allocated yet to it.

The correct usage would be something like that:

int main()
{
   uint64_t seed = 1;
   uint64_t hash_otpt[2];  // allocate 128 bits
   const char *key = "hi";
   MurmurHash3_x64_128(key, (uint64_t)strlen(key), seed, hash_otpt);
   cout << "hashed" << hash_otpt[0] << hash_otpt[1] << endl;
   return 0;
 }

You could have noticed that by analyzing how MurmurHash3_x86_128 fills out parameter:

((uint64_t*)out)[0] = h1;
((uint64_t*)out)[1] = h2;
Amadeus
  • 10,199
  • 3
  • 25
  • 31
  • does it means that the output is split into 2 incase MurmurHash3_x64_128 and split into four in MurmurHash3_x86_128? did i get that right? – ma1169 Aug 11 '21 at 20:34
1

hash_otpt is a pointer to nothing, but the function expects the fourth argument to be a pointer to some memory as it writes its output into this memory. In your example, it attempts a write operation, but fails (there's nowhere to write to as the pointer is not initialized). This gives you a SegmentationFault.

Figure out in how many uint64_ts does the hash fit into (2, because the output's size is 128 bits, and the size of a uint64_t is 64 bits) and allocate the memory:

hash_otpt = new uint64_t [2];
ForceBru
  • 43,482
  • 10
  • 63
  • 98
  • Or better `const size_t needed_size=2; uint64_t hash_otpt[needed_size];` (The constant 2 found by inspecting the source.) – Martin Bonner supports Monica Aug 19 '16 at 11:19
  • We also need to clarify what should `len` be. Does it tell length of `key` (it declared as pointrer to `void`, not `char`, so it doesn't look like function wants C string) or `out`? Impossible to tell without that specific lib knowledge – mvidelgauz Aug 19 '16 at 11:20
0

If you look at the documentation, you can see

MurmurHash3_x64_128 ... It has a 128-bit output.

So, your code can be something like this

    uint64_t hash_otpt[2]; // This is 128 bits
    MurmurHash3_x64_128(key, (uint64_t)strlen(key), seed, hash_otpt);

Note that you don't have to dynamically allocate the output at all.

Alexander Torstling
  • 18,552
  • 7
  • 62
  • 74
Ami Tavory
  • 74,578
  • 11
  • 141
  • 185