I have a class (let's call this "Common") that is used to create timers and call a member function from another class (let's call this "A") when the timer expires. The general idea is this: - A calls a function from Common passing it a pointer to the member function that is to be executed when the timer expires - Common stores the pointer to the function in a map with key of timer id - When the timer hits, the map is searched for the matching key and then the associated function is called.
Here is the code for A:
void A::setTimer()
{
std::function<void(void)> handler = std::bind(&A::onEventFunc, this);
pCommon->scheduleTimer(&handler);
}
onEventFunc is a public function of class A that does something when the timer expires.
Here is the code for Common:
static void timerHandler(int sig, siginfo_t *si, void uc)
{
map<timer_t*, std::function<void>(void)>*)::iterator iter =
globalTimerMap.find((timer_t*)si->si_value.sival_ptr);
if (iter != globalTimerMap.end)
{
std::function<void>(void)>* handler = iter->second;
(*handler)();
}
}
Common::schedulerTimer(std::function<void>(void)* handler)
{
// uses Linux timer_create and timer_settime
// code for these excluded EXCEPT the relevant lines
sa.sa_sigaction = timerHandler;
// bunch of other code here for timer_create and timer_settime
// insert into map
globalTimerMap.insert(pair(&timerid, handler);
}
This all compiles and runs just fine UNTIL it hits the (*handler)(); line which gives a segmantation fault.
I am new to boost and Linux programming and any knowledge that I have with C++ was gained from on the job training. This makes me believe that I am doing something really silly/stupid but I just don't know what it is. Is what I am trying to do even supposed to work?
The following line:
std::function<void(void)> handler = std::bind(&A::onEventFunc, this);
This creates a local variable on the stack (local to your setTimer
member function). What this means is your pointers in your map are all pointing to invalid memory.
I would change your map to store actual std::function
objects rather than pointers.
If you insist on storing pointers in your map, you will need to dynamically allocate the memory so that the memory remains valid:
std::function<void(void)>* handler = new std::function<void()>(std::bind(&A::onEventFunc, this));
However, you would be then required to delete
the memory to avoid memory leaks, so another alternative would be to use std::unique_ptr
in your map to handle that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With