在调用函子时删除它安全吗?

Is it safe to delete a functor while calling it?

本文关键字:安全 删除 调用      更新时间:2023-10-16

假设我有以下代码:

typedef std::function<void ()> func_type;
void some_func()
{
  // Irrelevant stuff here. Might take some time...
}
DWORD WINAPI thread_proc(LPVOID lpParameter)
{
  func_type& func = *static_cast<func_type*>(lpParameter);
  func();
  return 0;
}
int main()
{
  HANDLE handle;
  {
    std::function<void ()> my_func(some_func);
    handle = ::CreateThread(NULL, 0, &thread_proc, &my_func, 0, NULL);
    // Here we consider my_func won't be destroyed before its operator() is called in the other thread.
    // I know nothing guarantees that, but let's just say it does for this sample.
  }
  ::WaitForSingleObject(handle, INFINITE);
  return EXIT_SUCCESS;
}

我目前的实现似乎工作,但这并不能证明我没有面临未定义行为。

这里my_func 可能在调用其operator()返回之前被销毁。但是,既然我在some_func()中没有提到my_func,这真的是个问题吗?

注意:我不能使用std::threadboost::thread不幸。我希望我能。

如果它在func()发生之前被销毁,那么您正在无效对象上调用成员函数。您需要创建一个副本,该副本将至少在func()调用之前有效。

这肯定是UB。你的评论是不正确的,没有什么可以保证在本地被销毁之前调用operator()。事实上,我认为它很可能在新线程开始执行之前被销毁。这样做:

typedef std::function<void ()> func_type;
void some_func()
{
  // Irrelevant stuff here. Might take some time...
}
DWORD WINAPI thread_proc(LPVOID lpParameter)
{
  func_type* func = static_cast<func_type*>(lpParameter);
  (*func)();
  delete func;
  return 0;
}
int main()
{
  HANDLE handle;
  {
    func_type* my_func = new func_type(some_func);
    handle = ::CreateThread(NULL, 0, &thread_proc, my_func, 0, NULL);
  }
  ::WaitForSingleObject(handle, INFINITE);
  return EXIT_SUCCESS;
}