c++ - 使用 std::bind 的函数回调导致段错误

标签 c++ boost

我有一个类(让我们称之为“Common”),用于创建计时器并在计时器到期时从另一个类(让我们称之为“A”)调用成员函数。 总体思路是这样的: - A 从 Common 调用一个函数,传递给它一个指向成员函数的指针,该成员函数将在计时器到期时执行 - Common 将指向函数的指针存储在具有计时器 ID 键的映射中 - 当计时器命中时,将在 map 中搜索匹配的键,然后调用关联的函数。

这是 A 的代码:

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

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

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

这一切都编译并运行得很好,直到它命中 (*handler)();给出段错误的行。

我是 boost 和 Linux 编程的新手,我对 C++ 的任何了解都是从工作培训中获得的。这让我相信我正在做一些非常愚蠢/愚蠢的事情,但我只是不知道它是什么。我正在努力做的事情是否应该奏效?

最佳答案

下面一行:

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

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

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

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

但是,您将需要删除内存以避免内存泄漏,因此另一种选择是在您的 map 中使用std::unique_ptr来处理该问题.

关于c++ - 使用 std::bind 的函数回调导致段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21999574/

相关文章:

c++ - 如何使用模板根据类型将元素添加到各种容器

c++ - boost 序列化和 double

c++ - 如何将 boost::bind(&myClass::fun, this, _1, _2, _3) 转换为 typedef void (*fun)(arg1, arg2, arg3)?

c++ - Boost iterator_facade 的常量正确性

c++ - 为什么 boost 如此大量地模板化?

c++ - 调用模板化类型的不同构造函数签名

c++ - Qt FramelessWindowHint 和 WA_TranslucentBackground 字体渲染

c++ - EnumChildWindows 还是 FindWindowEx?

c++初学者使用while循环生成随机数

c++ - Boost.Regex 表达式构建