【发布时间】:2013-02-27 19:24:20
【问题描述】:
最近我开始处理一个遗留项目并尝试修复段错误(双重删除)。其中许多发生在boost::shared_ptr 析构函数或operator=(在包含shared_ptr 的对象上)。该代码包含大量使用 shared_ptr-s,包括复制、reset()-ing、分配等。根据boost docs,我们没有有效的用法 - 在许多线程中破坏/复制/重置相同的 shared_ptr 是不安全的。
每次都锁定似乎是不可能的,所以我正在寻找 boost::shared_ptr 的替代品。所以问题是:如果我用std::shared_ptr 或std::tr1::shared_ptr 替换所有boost::shared_ptr 会解决这个问题吗?似乎 tr1 是更安全的版本,但对我来说并不清楚。第二个问题 - c++0x 版本是否比 tr1 更好? (注意我们有 gcc 4.4.6,无法升级)
根据gcc docs,c++11 std::shared_ptr 应该可以解决这个问题,但我不确定 gcc4.4 版本...
UPD:刚刚进行了实验,现在我知道所有 3 个实现都在此代码上存在段错误(gcc 4.4).. 似乎我应该制作自定义类或其他解决方法...
#include <iostream>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
typedef boost::shared_ptr<int> ptrtype;
ptrtype p(new int);
void test() {
for(long i=0; i<1000000; ++i) {
ptrtype p1 = p;
p = ptrtype();
p.reset( new int );
}
}
int main() {
boost::thread_group tg;
for(int i=0; i<100; ++i) tg.add_thread( new boost::thread(test) );
tg.join_all();
std::cout << "Normal exit\n";
return 0;
}
【问题讨论】:
-
boost::shared_ptr 非常可靠。我认为用另一种实现替换它不会“解决”任何问题。如果您看到双重删除,那么您将继续看到这些,直到您找到并修复您的错误。
-
“每次都似乎不可能锁定”表示您遇到线程问题。更改智能指针实现不会给您带来任何好处。 boost::shared_ptr 没有问题。
-
您在寻找线程安全的共享指针吗?
-
我不是说它有问题。我们的代码有问题,它以在 boost 文档中标记为“未定义行为”的方式使用 shared_ptr。 (用链接更新了答案)
-
我怀疑更改特定的 shared_ptr 会修复您的代码。