ChunkCorner.h
#pragma once
#include <filesystem>
#include <iostream>
class ChunkCorner
{
public:
int x;
int y;
std::filesystem::path to_filename();
};
size_t hf(const ChunkCorner &chunk_corner);
bool eq(const ChunkCorner &c1, const ChunkCorner &c2);
ChunkCorner.cpp: fwiw: The hf and eq function implementation is based on the C Book p. 917.
#include "ChunkCorner.h"
using namespace std;
size_t hf(const ChunkCorner &chunk_corner)
{
return hash<int>()(chunk_corner.x) ^ hash<int>()(chunk_corner.y);
}
bool eq(const ChunkCorner &c1, const ChunkCorner &c2)
{
return c1.x == c2.x && c1.y == c2.y;
}
[...]
In another bit of code I use the class as follows:
unordered_set<ChunkCorner, decltype(&hf), decltype(&eq)> chunks_to_load {};
ChunkCorner c {1,2};
chunks_to_load.insert(c);
On the insert call I get a segfault (determined using breakpoints).
I use VS Code and when I launch the program in debug mode, it jumps to the following bit on segfault in hashtable_policy.h
:
__hash_code
_M_hash_code(const _Key& __k) const
{
static_assert(__is_invocable<const _H1&, const _Key&>{},
"hash function must be invocable with an argument of key type");
return _M_h1()(__k);
}
I am new to C and have trouble understanding what the issue is and I am not sure how to proceed debugging...
CodePudding user response:
You need to pass the hash and equals functions to your constructor. You've declared their type in the type arguments, which is going to be a pointer to function, but you haven't passed them in. So they're likely being zero initalized, so nullptr. Using them correctly should be done like this:
unordered_set<ChunkCorner, decltype(&hf), decltype(&eq)> chunks_to_load {16, hf, eq};
However, what I recommend is rewrite your Hash/Equals functions into function objects. This way, the default operations will work properly.
struct MyHasher {
size_t operator()(const ChunkCorner &chunk_corner) const
{
return hash<int>()(chunk_corner.x) ^ hash<int>()(chunk_corner.y);
}
};
struct MyEq {
bool operator()(const ChunkCorner &c1, const ChunkCorner &c2) const
{
return c1.x == c2.x && c1.y == c2.y;
}
};