使用std :: bind进行函数回调会导致分段错误

时间:2014-02-24 21:38:06

标签: c++ boost

我有一个类(让我们称之为“Common”),用于创建计时器,并在计时器到期时从另一个类调用成员函数(让我们称之为“A”)。 一般的想法是这样的: - A从Common调用函数,向其传递指向计时器到期时要执行的成员函数的指针 - Common使用timer id键在地图中存储指向函数的指针 - 当计时器命中时,将搜索映射以查找匹配的键,然后调用相关的函数。

以下是A:

的代码
void A::setTimer()
{ 
   std::function<void(void)> handler = std::bind(&A::onEventFunc, this);
   pCommon->scheduleTimer(&handler);
}

onEventFunc是A类的公共函数,它在计时器到期时执行某些操作。

以下是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);
}

这一切都编译并运行得很好UNTIL它命中(* handler)();给出分离错误的行。

我是新手,用于提升和Linux编程,我从C ++获得的任何知识都来自于在职培训。这让我相信我正在做一些非常愚蠢/愚蠢的事情,但我只是不知道它是什么。我想做什么甚至应该工作?

1 个答案:

答案 0 :(得分:5)

以下一行:

std::function<void(void)> handler = std::bind(&A::onEventFunc, this);

这会在堆栈上创建一个局部变量(setTimer成员函数的本地变量)。这意味着你的地图中的指针都指向无效的内存。

我会更改您的地图以存储实际的std::function对象而不是指针。 如果您坚持在地图中存储指针,则需要动态分配内存以使内存保持有效:

std::function<void(void)>* handler = new std::function<void()>(std::bind(&A::onEventFunc, this));

但是,您需要delete内存以避免内存泄漏,因此另一种方法是在地图中使用std::unique_ptr来处理内存泄漏。