segfault with self-declared hash function - c++

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...

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;
}
};

Related

when I am using this comparator function without static keyword it giving error [duplicate]

trying to compile the following code I get this compile error, what can I do?
ISO C++ forbids taking the address of
an unqualified or parenthesized
non-static member function to form a
pointer to member function.
class MyClass {
int * arr;
// other member variables
MyClass() { arr = new int[someSize]; }
doCompare( const int & i1, const int & i2 ) { // use some member variables }
doSort() { std::sort(arr,arr+someSize, &doCompare); }
};
doCompare must be static. If doCompare needs data from MyClass you could turn MyClass into a comparison functor by changing:
doCompare( const int & i1, const int & i2 ) { // use some member variables }
into
bool operator () ( const int & i1, const int & i2 ) { // use some member variables }
and calling:
doSort() { std::sort(arr, arr+someSize, *this); }
Also, isn't doSort missing a return value?
I think it should be possible to use std::mem_fun and some sort of binding to turn the member function into a free function, but the exact syntax evades me at the moment.
EDIT: Doh, std::sort takes the function by value which may be a problem. To get around this wrap the function inside the class:
class MyClass {
struct Less {
Less(const MyClass& c) : myClass(c) {}
bool operator () ( const int & i1, const int & i2 ) {// use 'myClass'}
MyClass& myClass;
};
doSort() { std::sort(arr, arr+someSize, Less(*this)); }
}
As Andreas Brinck says, doCompare must be static (+1). If you HAVE TO have a state in your comparator function (using the other members of the class) then you'd better use a functor instead of a function (and that will be faster):
class MyClass{
// ...
struct doCompare
{
doCompare( const MyClass& info ) : m_info(info) { } // only if you really need the object state
const MyClass& m_info;
bool operator()( const int & i1, const int & i2 )
{
// comparison code using m_info
}
};
doSort()
{ std::sort( arr, arr+someSize, doCompare(*this) ); }
};
Using a functor is always better, just longer to type (that can be unconvenient but oh well...)
I think you can also use std::bind with the member function but I'm not sure how and that wouldn't be easy to read anyway.
UPDATE 2014: Today we have access to c++11 compilers so you could use a lambda instead, the code would be shorter but have the exact same semantic.
The solution proposed by Rob is now valid C++11 (no need for Boost):
void doSort()
{
using namespace std::placeholders;
std::sort(arr, arr+someSize, std::bind(&MyClass::doCompare, this, _1, _2));
}
Indeed, as mentioned by Klaim, lambdas are an option, a bit more verbose (you have to "repeat" that the arguments are ints):
void doSort()
{
std::sort(arr, arr+someSize, [this](int l, int r) {return doCompare(l, r); });
}
C++14 supports auto here:
void doSort()
{
std::sort(arr, arr+someSize, [this](auto l, auto r) {return doCompare(l, r); });
}
but still, you declared that arguments are passed by copy.
Then the question is "which one is the most efficient". That question was treated by Travis Gockel: Lambda vs Bind. His benchmark program gives on my computer (OS X i7)
Clang 3.5 GCC 4.9
lambda 1001 7000
bind 3716166405 2530142000
bound lambda 2438421993 1700834000
boost bind 2925777511 2529615000
boost bound lambda 2420710412 1683458000
where lambda is a lambda used directly, and lambda bound is a lambda stored in a std::function.
So it appears that lambdas are a better option, which is not too much of a surprise since the compiler is provided with higher level information from which it can make profit.
You can use boost::bind:
void doSort() {
std::sort(arr,arr+someSize, boost::bind(&MyClass::doCompare, this, _1, _2));
}
There is a way to do what you want, but you need to use a small adaptor. As the STL doesn't write it for you, can can write it yourself:
template <class Base, class T>
struct adaptor_t
{
typedef bool (Base::*method_t)(const T& t1, const T& t2));
adaptor_t(Base* b, method_t m)
: base(b), method(m)
{}
adaptor_t(const adaptor_t& copy) : base(copy.base), method(copy.method) {}
bool operator()(const T& t1, const T& t2) const {
return (base->*method)(t1, t2);
}
Base *base;
method_t method;
}
template <class Base, class T>
adaptor_t<Base,T> adapt_method(Base* b, typename adaptor_t<Base,T>::method_t m)
{ return adaptor_t<Base,T>(b,m); }
Then, you can use it:
doSort() { std::sort(arr,arr+someSize, adapt_method(this, &doCompare)); }
The third argument in the calling of std::sort() is not compatible to the function pointer needed by std::sort(). See my answer to another question for a detailed explanation for why a member function signature is different from a regular function signature.
just make your helper function, static which you are going to pass inside the sort function.
for e.g
struct Item
{
int val;
int id;
};
//Compare function for our Item struct
static bool compare(Item a, Item b)
{
return b.val>a.val;
}
Now you can pass this inside your sort function
A very simple way to effectively use a member function is to use operator<. That is, if you have a function called compare, you can call it from operator<. Here is a working example:
class Qaz
{
public:
Qaz(int aX): x(aX) { }
bool operator<(const Qaz& aOther) const
{
return compare(*this,aOther);
}
static bool compare(const Qaz& aP,const Qaz& aQ)
{
return aP.x < aQ.x;
}
int x;
};
Then you don't even need to give the function name to std::sort:
std::vector<Qaz> q;
q.emplace_back(8);
q.emplace_back(1);
q.emplace_back(4);
q.emplace_back(7);
q.emplace_back(6);
q.emplace_back(0);
q.emplace_back(3);
std::sort(q.begin(),q.end());
Updating Graham Asher answer, as you don't need the compare but can use the less operator directly.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Qaz {
public:
Qaz(int aX): x(aX) { }
bool operator<(const Qaz& aOther) const {
return x < aOther.x;
}
int x;
};
int main() {
std::vector<Qaz> q;
q.emplace_back(8);
q.emplace_back(1);
q.emplace_back(4);
q.emplace_back(7);
q.emplace_back(6);
q.emplace_back(0);
q.emplace_back(3);
std::sort(q.begin(),q.end());
for (auto& num : q)
std::cout << num.x << "\n";
char c;
std::cin >> c;
return 0;
}

Using std::less<> for unique_ptr to raw pointer comparison fails to compile, but works with wrapper?

I want to search by raw pointer in a set of std::unique_ptr, and instead of writing my own comparator class I decided to use the transparent property of std::less<>.
Here's an example code based on the cppreference example.
This doesn't compile:
#include <memory>
#include <set>
using FatKey = std::unique_ptr<int>;
using LightKey = int;
bool operator<(const FatKey& fk, LightKey* lk) { return fk.get() < lk; }
bool operator<(LightKey* lk, const FatKey& fk) { return lk < fk.get(); }
bool operator<(const FatKey& fk1, const FatKey& fk2) { return fk1.get() < fk2.get(); }
int main()
{
std::set<FatKey, std::less<>> example2;
LightKey lk = 2;
auto search2 = example2.find(&lk);
}
While this works fine:
#include <memory>
#include <set>
template<typename T>
struct UPtrWrapper { std::unique_ptr<T> ptr; };
using FatKey = UPtrWrapper<int>;
using LightKey = int;
bool operator<(const FatKey& fk, LightKey* lk) { return fk.ptr.get() < lk; }
bool operator<(LightKey* lk, const FatKey& fk) { return lk < fk.ptr.get(); }
bool operator<(const FatKey& fk1, const FatKey& fk2) { return fk1.ptr.get() < fk2.ptr.get(); }
int main()
{
std::set<FatKey, std::less<>> example2;
LightKey lk = 2;
auto search2 = example2.find(&lk);
}
The FatKey is passed by const ref in both cases, they are both template classes, neither of them is copy constructible, but still only one of them works.
What am I missing here?
Neither std::unique_ptr<int> nor int involve user-defined types; in terms of ADL their associated namespaces are namespace std only.
When you use a wrapper type you have an associated namespace of the root namespace (the namespace where you declared the wrapper), which means that ADL can find the free operator<s defined there.
Indeed, this is a Good Thing since it prevents someone else writing their own operator<(int*, std::unique_ptr<int> const&) which might have a different behavior to yours.
ecatmur already answered that the first example didn't work due to ADL.
I just want to show how you can create your std::set without needing all these extra functions:
auto PtrCmp = [](std::unique_ptr<int> const & lhs,
std::unique_ptr<int> const & rhs) {
return lhs.get() < rhs.get();
};
auto orderedPtrSet = std::set<std::unique_ptr<int>, decltype(PtrCmp)>(PtrCmp);
Note: I realize this is not a real answer to the question, but it's a little too long to put in a comment. And it seems to me it might be interesting for OP.

working with expressions: how to minimize runtime construction time

I have two classes, a single expression (SE) and a bundle of two expressions (ME). The bundle is an expression itself, hence it can be an element of another bundle.
struct SE {
SE(char id, char n) : id(id), n(n) {}
size_t size() const { return n; }
char *eval(char *b) const { b[0]=id; return b+1; }
char id, n;
};
template <typename LHS>
struct ME {
ME(const LHS& l, const SE& r) : lhs(l), rhs(r) { }
size_t size() const { return rhs.size(); }
char *eval(char *b) const { *b++='('; b=lhs.eval(b); *b++=','; b=rhs.eval(b); *b++=')'; return b; }
LHS lhs;
SE rhs;
};
The construction of the bundle performs a simple validity check based on the data member n, accessible in ME via the method size. An eval method does some claculations using the data member id. Neither n nor id are known at compile time.
For both classes I override the comma operator, so that it performs the recursive bundling of multiple single expression into a nested bundle.
auto SE::operator,(const SE& r) { return ME<SE>(*this, r); }
auto ME<LHS>::operator,(const SE& r) { return ME<ME<LHS>>(*this, r); }
I want that, after the whole bundle has been constructed, the method eval is triggered on the whole bundle. Example:
SE('a',1); // prints 'a'
SE('a',1), SE('b',1); // prints '(a,b)'
SE('a',1), SE('b',1), SE('c',1); // prints '((a,b),c)'
A possible way to achieve that is to use the destructors of the classes and add a flag is_outer which is updated appropriately during contruction of SE and ME. When any of these class is destructed, if the flag indicates this is the outermost class, then eval is triggered. A full demo is given below.
Testing on godbolt the simple demo function below, it seems to me the compiler generates more code than strictly necessary. Although id and n are not known at compile time, the final type of the expression should be. I would expect the entire construction of the bundle to reduce to just moving a few numbers in the correct place, then check the assertions, but it seems to actually do much more copies.
Is it possible to obtain that more of the contruction part is produced at compile time?
#include <iostream>
#include <cassert>
#include <string>
#include <sstream>
using namespace std;
// forward declaration
template <typename LHS> struct ME;
struct SE {
SE(char id, char n) : id(id), n(n), outer(true) {}
SE(const SE& expr) : id(expr.id), n(expr.n), outer(false) {}
ME<SE> operator,(const SE& r);
size_t size() const { return n; }
char *eval(char *b) const { b[0]=id; return b+1; }
~SE() { if(outer) { char b[20] = {}; char *p=eval(b); *p++='\n'; cout << b; } }
char id, n;
mutable bool outer;
};
template <typename LHS>
struct ME {
ME(const LHS& l, const SE& r)
: lhs(l), rhs(r), outer(true) // tentatively set to true
{ l.outer = r.outer = false; assert(l.size() == r.size()); } // reset flag for arguments
ME(const ME<LHS>& expr)
: lhs(expr.lhs), rhs(expr.rhs), outer(false) {}
size_t size() const { return rhs.size(); }
char *eval(char *b) const { *b++='('; b=lhs.eval(b); *b++=','; b=rhs.eval(b); *b++=')'; return b; }
auto operator,(const SE& r) { return ME<ME<LHS>>(*this, r); }
~ME() { if(outer) { char b[20] = {}; char *p=eval(b); *p++='\n'; cout << b; } }
LHS lhs;
SE rhs;
mutable bool outer;
};
ME<SE> SE::operator,(const SE& r) { return ME<SE>(*this, r); }
void demo(char a, char na, char b, char nb, char c, char nc) {
SE(a, na), SE(b,nb), SE(c,nc); // prints '((a,b),c)'
}
int main() {
demo('a',1,'b',1,'c',1);
return 0;
}
The general pattern you are following is expression templates. Reading up on how others do it will help.
Usually expression templates use CRTP heavily, and do not store copies.
I believe I see bugs due to the copies.
Generally take T&& and store T& or T&&.
Usually expression templates terminate (and execute) when they are assigned to a target; you don't want to that. As C++ lacks move-from-and-destroy, you have to check the "should not be executed" at (nominally) runtime.
Instead of references/values and a bool, you could store pointers and use null as the "don't run" case.
I cannot figure out how to make the work to determine what to run constexpr. It might be possible however.

How to create a set with my customized comparison in c++

Could someone explain me what is going on in this example here?
They declare the following:
bool fncomp (int lhs, int rhs) {return lhs<rhs;}
And then use as:
bool(*fn_pt)(int,int) = fncomp;
std::set<int,bool(*)(int,int)> sixth (fn_pt)
While the example for the sort method in algorithm library here
can do like this:
bool myfunction (int i,int j) { return (i<j); }
std::sort (myvector.begin()+4, myvector.end(), myfunction);
I also didn't understand the following:
struct classcomp {
bool operator() (const int& lhs, const int& rhs) const
{return lhs<rhs;}
};
this keyword operator (not being followed by an operator as in a op. overload)... what is the meaning of it? Any operator applied there will have that behavior? And this const modifier... what is the effect caused by it?
I was trying to make a set of C-style string as follows:
typedef struct
{
char grid[7];
} wrap;
bool compare(wrap w1, wrap w2)
{
return strcmp(w1.grid, w2.grid) == -1;
}
set <wrap, compare> myset;
I thought I could create a set defining my sorting function in a similar as when I call sort from algorithm library... once it didn't compile I went to the documentation and saw this syntax that got me confused... Do I need to declare a pointer to a function as in the first example i pasted here?
struct classcomp {
bool operator() (const int& lhs, const int& rhs) const
{return lhs<rhs;}
};
Defines a functor by overloading the function call operator. To use a function you can do:
int main() {
std::set <wrap, bool (*)(wrap,wrap)> myset(compare);
return 0;
}
Another alternative is to define the operator as a part of the wrap class:
struct wrap {
char grid[7];
bool operator<(const wrap& rhs) const {
return strcmp(this->grid, rhs.grid) == -1;
}
};
int main() {
wrap a;
std::set <wrap> myset;
myset.insert(a);
return 0;
}
You're almost there... here's a "fixed" version of your code (see it run here at ideone.com):
#include <iostream>
#include <set>
#include <cstring>
using namespace std;
typedef struct
{
char grid[7];
} wrap;
bool compare(wrap w1, wrap w2) // more efficient: ...(const wrap& e1, const wrap# w2)
{
return strcmp(w1.grid, w2.grid) < 0;
}
set <wrap, bool(*)(wrap, wrap)> myset(compare);
int main() {
wrap w1 { "abcdef" };
wrap w2 { "ABCDEF" };
myset.insert(w1);
myset.insert(w2);
std::cout << myset.begin()->grid[0] << '\n';
}
"explain [to] me what is going on in this example"
Well, the crucial line is...
std::set<wrap, bool(*)(wrap, wrap)> myset(compare);
...which uses the second template parameter to specify the type of function that will perform comparisons, then uses the constructor argument to specify the function. The set object will store a pointer to the function, and invoke it when it needs to compare elements.
"the example for the sort method in algorithm library..."
std::sort in algorithm is great for e.g. vectors, which aren't automatically sorted as elements are inserted but can be sorted at any time. std::set though needs to maintain sorted order constantly, as the logic for inserting new elements, finding and erasing existing ones etc. all assumes the existing elements are always sorted. Consequently, you can't apply std::sort() to an existing std::set.
"this keyword operator (not being followed by an operator as in a op. overload)... what is the meaning of it? Any operator applied there will have that behavior? And this const modifier... what is the effect caused by it?
operator()(...) can be invoked on the object using the same notation used to call a function, e.g.:
classcomp my_classcomp;
if (my_classcomp(my_int1, my_int_2))
std::cout << "<\n";
As you can see, my_classcomp is "called" as if it were a function. The const modifier means that the code above works even if my_classcomp is defined as a const classcomp, because the comparison function does not need to modify any member variables of the classcomp object (if there were any data members).
You almost answered your question:
bool compare(wrap w1, wrap w2)
{
return strcmp(w1.grid, w2.grid) == -1;
}
struct wrap_comparer
{
bool operator()(const wrap& _Left, const wrap& _Right) const
{
return strcmp(_Left.grid, _Right.grid) == -1;
}
};
// declares pointer to function
bool(*fn_pt)(wrap,wrap) = compare;
// uses constructor with function pointer argument
std::set<wrap,bool(*)(wrap,wrap)> new_set(fn_pt);
// uses the function directly
std::set<wrap,bool(*)(wrap,wrap)> new_set2(compare);
// uses comparer
std::set<wrap, wrap_comparer> new_set3;
std::sort can use either a function pointer or a function object (http://www.cplusplus.com/reference/algorithm/sort/), as well as std::set constructor.
const modifier after function signature means that function can't modify object state and so can be called on a const object.

problem with `==` operator

There is some class wComplex with == operator.
#ifndef WCOMPLEX_H
#define WCOMPLEX_H
#include <stdio.h>
// sample class of complex-like numbers with weird `==` operator
class wComplex{
private:
double realPart;
double imagePart;
public:
wComplex();
wComplex(double R);
wComplex(double R, double I);
bool operator==(wComplex &);
void print();
};
wComplex::wComplex(){
realPart = 0;
imagePart = 0;
}
wComplex::wComplex(double R){
realPart = R;
imagePart = 0;
}
wComplex::wComplex(double R, double I)
{
realPart = R;
imagePart = I;
}
bool wComplex::operator==(wComplex &El){
double diff = realPart*realPart + imagePart*imagePart -
El.realPart*El.realPart - El.imagePart*El.imagePart;
return (diff == 0);
}
void wComplex::print(){
printf("(%g) + (%g)i\n", realPart, imagePart);
}
#endif
It successfully worked with stuff like that:
wComplex A(1, 2);
wComplex B(2, 4);
wComplex C(2, 1);
(A==C) is true.
There is another class - queue-like. But it should control the new pushed element for equality (in == meaning) of other elements.
#ifndef MYQueue_H
#define MYQueue_H
#include <stdio.h>
#include <queue>
template<typename T>
class myQueue : public std::queue<T>{
public:
myQueue(){
printf("new myQueue successfully created\n");
}
void push (const T& x){
myQueue* tmp = new myQueue;
myQueue* old = new myQueue;
old = this;
bool MATCH = false;
while(!old->empty()){
T el = old->front();
if(el == x){
MATCH = true;
tmp->push(x);
}
else
tmp->push(el);
old->pop();
}
if(!MATCH)
tmp->push(x);
this = *tmp;
delete tmp;
delete old;
}
};
#endif
So, now there is one problem
myqueue.h: In member function ‘void myQueue<T>::push(const T&) [with T = wComplex]’:
shit.cpp:23: instantiated from here
myqueue.h:26: error: no match for ‘operator==’ in ‘el == x’
wcomplex.h:36: note: candidates are: bool wComplex::operator==(wComplex&)
myqueue.h:36: error: lvalue required as left operand of assignment
make: *** [compile] Error 1
Actually, I can't understand why no match for ‘operator==’ in ‘el == x’
And what should I do? Any ideas
UPD: and how can I replace this element by tmp?
It's something wrong with this = *tmp;
You have a const reference to T in push() but your operator== only accepts non-const references.
bool wComplex::operator==(wComplex &El)
should be
bool wComplex::operator==(wComplex const &El) const
Or, optimally, your operator== should be a free function:
bool operator==(wComplex const & Left, wComplex const & Right) {
}
If you don't want outside access to the member variables of wComplex, you'll need to make the operator a friend function:
class wComplex {
...
friend bool operator==(wComplex const & Left, wComplex const & Right);
...
};
EDIT: On the updated question:
You cannot assign to this. this is of type T * const - since it wouldn't make sense to modify it. What you're trying to do is to change an external variable which points to the current class, you cannot do that from inside a class member function unless this external variable is passed in as an argument.
I think you need to make a "queue" class which manages "node" class instances - trying to combine a container and the contained elements isn't really a good idea
Also, inheriting standard library containers is rarely a good idea. If you want to use a std::queue then make a member variable.
Change:
bool wComplex::operator==(wComplex &El){
into:
bool wComplex::operator==(const wComplex &El) const {
One tips for the future:
The const keyword, either you put it nowhere, or everywhere you can.
Obviously, everywhere you can is better.