Under g++ 4.8.5 compiling, it is found that improper use of sharedptr will cause multiple destruction of shared_ptr.
Fake code:
#include<memory>
class Demo
{
public:
~Demo()
{
// Do something and cost some milliseconds
}
};
typedef std::shared_ptr<Demo> DemoPtr;
DemoPtr global_demo;
DemoPtr instance() {return global_demo;}
// Main thread
int main()
{
global_demo = std::make_shared<Demo>();
// Do something
}
// Thread A
void thread_func()
{
// Do something
if(instance() != nullptr)
{
// Do something
}
// Do something
}
When the main thread ends, the global_demo reference count is reduced to 0, and global_demo begins to be destructed. When global_demo is being destructed, thread A calls instance() and makes a judgment, which causes the reference count of global_demo to increase by one again, and then when the local variable is released, the reference count is reduced to 0 again, resulting in the destruction of the object pointed to by global_demo The function is called again.
View gcc source code:
//*************__shared_count***************//
__shared_count&
operator=(const __shared_count& __r) noexcept
{
_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
if (__tmp != _M_pi)
{
if (__tmp != 0)
__tmp->_M_add_ref_copy();
if (_M_pi != 0)
_M_pi->_M_release();
_M_pi = __tmp;
}
return *this;
}
//************_Sp_counted_base*****************//
void
_M_add_ref_copy()
{ __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
So, this is a GCC bug?
Should I use std::weak_ptr to solve this problem in this case? So, my instance() method code like this?
DemoPtr instance()
{
std::weak_ptr<Demo> w(global_demo);
if(!w.expired())
{
return w.lock();
}
return nullptr;
}
Aucun commentaire:
Enregistrer un commentaire