【问题标题】:Why boost::thread could be deleted double times?为什么 boost::thread 可以被删除两次?
【发布时间】:2011-09-14 13:11:59
【问题描述】:

我注意到了一些奇怪的事情。我希望运行以下代码会产生段错误,但事实并非如此。

void DeadlineTimeOut(const boost::system::error_code& pErrorCode, boost::thread* pThread) 
{
    std::cout << "Error code: #" << pErrorCode.value() 
      << " Message: " << pErrorCode.message() << std::endl;
    std::cout << "Thread Address = " 
      << pThread << std::endl; // "sth. like 0x33aabc0"

    pThread->interrupt();
    pThread->join();

    delete pThread;
    delete pThread;

    std::cout << "Stopped execution thread #" 
      << pThread->get_id() << std::endl; // "{Not-any-thread}"
}

那么,为什么双重删除是可能的?还打电话给会员?我现在有点迷茫。

【问题讨论】:

  • 这是一个完全有效的问题。为什么投反对票?
  • 为了更好的阅读做了一些改动,抱歉我一开始错过了这个
  • 反对票可能源于使用boost::thread 掩盖了问题这一事实。 int* 也一样,我们可以简单地将其作为 dup 关闭。
  • @pmr:这是有道理的。像往常一样,如果人们在投反对票时不要忽略那个橙色的小窗口,那就太好了。

标签: c++ multithreading memory-management boost


【解决方案1】:

两次删除指针是undefined behaviour。不能保证段错误。如果你幸运的话,你可能会得到一个;你可能不会。该代码可能会通过您的所有测试,然后在最糟糕的时刻在您的客户面前炸毁。请参阅C++ FAQ

取消引用已删除的指针(代码中的 pThread-&gt;get_id())也是如此。

一个简单的防御技术是在指针被删除后立即将其设置为 NULL,而不是让它们dangle。这可能有助于捕获 一些 此类错误。

以上适用于 any 类型的指针,而不仅仅是boost::thread*

【讨论】:

  • 不能说我同意将指针设置为NULL。这真的不能防御任何东西。大多数情况下,被删除的指针无论如何都会立即超出范围,并且将此指针设置为NULL 不会对指向同一对象的其他指针做任何事情(并且这些指针也变得无效)。
  • @Martin:我完全同意 James 关于这个问题的看法。将指针设置为NULL 只会掩盖错误。处理不再需要的指针的最佳方法是让它超出其范围。在这方面,将指针设置为 NULL 类似于将祈祷作为避孕药:听起来不错,但没有帮助。
  • @Nic:还是 另一个 25-30 行?看来你的函数太长了。
  • @Nicol:我很少使用裸指针,而且我至少有十年没有使用它们来管理资源,除非是作为唯一目的是管理该资源的类的成员。在那里,您的 delete ptr_; 在 dtor 中,就在关闭 } 之前。
  • @Nicol:我应该感到被冒犯了吗?我从 1994 年开始为了钱而编写 C++。我参与过很多 C++ 项目,从作为唯一的开发人员到合作开发数百万个 LoC 项目,我使用了十年前的代码库。很有可能您安装了我的一些代码(它是一些安装了数百万次的流行应用程序的一部分),或者您正在通过网络上的某些服务器使用它(我的一些代码在谷歌和其他网络服务器上运行) . 无论我身在何处,我都发现使用裸指针与看到“莫名其妙”的崩溃之间存在很强的相关性。
猜你喜欢
  • 2014-02-25
  • 2012-09-26
  • 2017-02-20
  • 1970-01-01
  • 2016-03-29
  • 1970-01-01
  • 2012-01-22
  • 1970-01-01
相关资源
最近更新 更多