Reputation: 47
This is a bit of a long winded question but I cannot figure out a simpler way of explaining what is going on.
First is this low level template class which contains the std::function
callback (assume HeaderOne and HeaderTwo are defined as two different structs):
template <class Type>
class TemplateClass
{
public:
template<class Type>
TemplateClass(Type t): type_{t} {}
std::function<void(char*, size_t)> on_callback;
void CheckHeader(char*, size_t);
private:
Type type_;
};
typedef TemplateClass<HeaderOne> HeaderOneClass;
typedef TemplateClass<HeaderTwo> HeaderTwoClass;
Then another class contains a map of HeaderTwoClass indexed by an int:
class Processor
{
public:
Processor(){}
void ProcessPacket(char*, size_t);
void AddHeaderClass(int i);
private:
std::map<int, HeaderTwoClass> hdrs_;
};
The implementation of AddHeaderClass
:
void Processor::AddHeaderClass(int i)
{
HeaderTwoClass new_hdr;
auto [it, inserted] = hdrs_.insert({i, std::move(new_hdr)});
it->second.on_callback = [this](char* d, size_t i){ this->ProcessPacket(d, i); };
}
There is some other socket class that calls HeaderTwoClass::CheckHeader
and if the check passes it calls on_callback
. The problem I get is that when on_callback
is called, the program segfaults.
If I replace the map with just a member of type HeaderTwoClass
the problem goes away.
I have tried to debug it by printing out the memory address of on_callback
but have found it does the following:
HeaderTwoClass
is first constructed, &on_callback = 123456HeaderTwoClass
is moved into the map, &on_callback =
78910on_callback
is first called, &on_packet = 123456.It seems that the on_callback is pointing to some area of memory before the std::move even though I set the callback after?
Any ideas? I'm stumped at this point. I also tried to write a minimal compile-able example to simplify and reproduce the error but was unable.
Note this code is all single threaded as well.
Upvotes: 0
Views: 251
Reputation: 11000
- when
HeaderTwoClass
is first constructed,&on_callback
=123456
- after the
HeaderTwoClass
is moved into the map,&on_callback
=78910
This isn't strange at all - you are checking the address of the std::function
member in the type (which is basically just an offset to this
). When you move the object into the map then end result is that it is move constructed - that means a new distinct object (albeit with a move it's semantically fine to steal or swap
resources off the old object). So perhaps this is the root to your issue. If you need to avoid that, use some pointer type instead (e.g. shared_ptr
) - or construct directly inside the map
using emplace
.
Upvotes: 1