Ste*_*han 5 c++ boost exc-bad-access boost-thread ios6
我正在为XCode 4.6中的iOS开发.我正在为服务编写一个库,并使用boost来启动线程.我的一个方法看起来像这样:
void Service::start(boost::shared_ptr<ResultListener> listener) {
boost::future<bool> con = boost::make_future(true);
listener->onConnected(); // Works
boost::future<bool> initDone = con.then([&, listener](boost::future<bool>& connected) {
listener->onConnected(); // Works
if (!connected.get()) {
listener->onError("...");
return false;
}
listener->onError("..."); // EXC_BAD_ACCESS
/* ... */
return true;
});
}
Run Code Online (Sandbox Code Playgroud)
在设备上执行此操作时,我会EXC_BAD_ACCESS
在标记的行处获得.我对此感到非常惊讶,因为第一次调用onConnected
是成功的,即使我在该onError
调用之前添加了一个调用if
也是有效的.
由于对C++缺乏经验,我会对每一条信息感到高兴,这些信息是关于什么原因,如何调试它以及如何在下次发生此问题时如何发现.此外,我不太确定哪些信息是相关的.我所知道的可能与我迄今为止所发现的相关,以下可能是:ResultListener
并且Service
是boost::noncopyable
.我检查了shared_ptr
(使用use_count
)的引用计数,它在继续中增加.我正在使用boost 1.53.这个方法就是这样调用的
Servuce reco(/* ... */);
boost::shared_ptr<foo> f(new foo());
reco.start(f);
Run Code Online (Sandbox Code Playgroud)
foo
是一个简单的类,std::cout
如果调用一个方法,它只会打印.
编辑:进一步窥探让我检查get()
调用,我发现以下代码future.hpp
正在执行:
// retrieving the value
move_dest_type get()
{
if(!this->future_)
{
boost::throw_exception(future_uninitialized());
}
future_ptr fut_=this->future_;
this->future_.reset();
return fut_->get();
}
Run Code Online (Sandbox Code Playgroud)
我认为这是问题所在.呼吁reset()
似乎释放了记忆future_
shared_ptr
.我的猜测是,这标志着listener
延迟仍在运行的内存,因为没有用于操作系统,因此使指针无效,然后指示内存访问超出其范围.这个假设是否正确?我可以以某种方式避免这种情况,或者这是一个提升中的错误?
编辑2:以下是创建问题的最小示例:
#define BOOST_THREAD_VERSION 4
#include <boost/thread.hpp>
class Test {
public:
void test() {
boost::shared_ptr<Test> listener(new Test());
boost::future<bool> con = boost::make_future(true);
listener->foo(); // Works
boost::future<bool> initDone = con.then([listener](boost::future<bool>& connected) {
listener->foo(); // Works
if (!connected.get()) {
listener->foo();
return false;
}
listener->foo(); // EXC_BAD_ACCESS
return true;
});
}
void foo() {
std::cout << "foo";
}
};
Run Code Online (Sandbox Code Playgroud)
我在XCode中添加了两个截图,以显示将来运行conitnuation的情况,看起来Mankarnas(在评论中)和我(上面)是正确的:似乎是存储延续的内存部分被释放,因此发生未定义的行为.
这就是之前的情况get()
:
我针对 boost 1.53 开了一张票,并被确认为一个错误。似乎future.then
还不稳定,因此尚未准备好用于生产使用。那里的一个建议是使用
#define BOOST_THREAD_DONT_PROVIDE_FUTURE_INVALID_AFTER_GET
Run Code Online (Sandbox Code Playgroud)
但明确指出该功能尚未稳定(并且文档缺乏这方面的信息)。
我现在已切换为使用单独的线程,在该线程中我将等待未来并执行正确的操作。
归档时间: |
|
查看次数: |
617 次 |
最近记录: |