使用 shared_ptr 的一個問題代碼

代碼如下:

#include <iostream>
#include <memory>
#include <list>

class A
{
public:
void Add();
void Delete();
~A();
private:
std::list< std::shared_ptr<A> > m_ptr;
};


void A::Add(void)
{
    m_ptr.push_back(std::shared_ptr<A> (this));
}

void A::Delete(void)
{
    m_ptr.remove(std::shared_ptr<A> (this));
}

A::~A()
{
    std::cout << "A destructor " << std::endl;
}

int main(void)
{
    A * pA = new A();
    pA->Add();
    pA->Delete();
    return 0;
}

運行的時候crash.

死機的時候的backtrace如下:

(gdb) bt full
#0  0x00011550 in std::_List_base<std::shared_ptr<A>, std::allocator<std::shared_ptr<A> > >::_M_clear (this=0x23008)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/list.tcc:73
        __tmp = 0x0
        __cur = 0x0
#1  0x00011130 in std::_List_base<std::shared_ptr<A>, std::allocator<std::shared_ptr<A> > >::~_List_base (this=0x23008, __in_chrg=<optimized out>)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/stl_list.h:378
No locals.
#2  0x00010e9c in std::list<std::shared_ptr<A>, std::allocator<std::shared_ptr<A> > >::~list (this=0x23008, __in_chrg=<optimized out>)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/stl_list.h:438
No locals.
#3  0x00010d0c in A::~A (this=0x23008, __in_chrg=<optimized out>)
    at test_delete.cpp:29
No locals.
#4  0x00011db4 in std::_Sp_counted_ptr<A*, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=0x23048)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/shared_ptr_base.h:290
---Type <return> to continue, or q <return> to quit---
No locals.
#5  0x0001122c in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x23048)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/shared_ptr_base.h:144
No locals.
#6  0x00010f3c in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0xbefffcb4, __in_chrg=<optimized out>)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/shared_ptr_base.h:546
No locals.
#7  0x00010e44 in std::__shared_ptr<A, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0xbefffcb0, __in_chrg=<optimized out>)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/shared_ptr_base.h:781
No locals.
#8  0x00010e70 in std::shared_ptr<A>::~shared_ptr (this=0xbefffcb0, 
    __in_chrg=<optimized out>)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/shared_ptr.h:93
No locals.
#9  0x00010cac in A::Delete (this=0x23008) at test_delete.cpp:23
No locals.
---Type <return> to continue, or q <return> to quit---
#10 0x00010d64 in main () at test_delete.cpp:35
        pA = 0x23008
从 log看,class A的析构函数被调用了两次。这可能是问题的原因。

第一次调用A的析构函数的backtrace:

(gdb) where
#0  A::~A (this=0x23008, __in_chrg=<optimized out>) at test_delete.cpp:28
#1  0x00011db4 in std::_Sp_counted_ptr<A*, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=0x23018)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/shared_ptr_base.h:290
#2  0x0001122c in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x23018)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/shared_ptr_base.h:144
#3  0x00010f3c in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x2303c, __in_chrg=<optimized out>)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/shared_ptr_base.h:546
#4  0x00010e44 in std::__shared_ptr<A, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0x23038, __in_chrg=<optimized out>)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/shared_ptr_base.h:781
#5  0x00010e70 in std::shared_ptr<A>::~shared_ptr (this=0x23038, 
    __in_chrg=<optimized out>)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/shared_ptr.h:93
#6  0x000117d8 in std::_List_node<std::shared_ptr<A> >::~_List_node (
    this=0x23030, __in_chrg=<optimized out>)
---Type <return> to continue, or q <return> to quit---
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/stl_list.h:106
#7  0x00011804 in __gnu_cxx::new_allocator<std::_List_node<std::shared_ptr<A> > >::destroy<std::_List_node<std::shared_ptr<A> > > (this=0x23008, __p=0x23030)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/ext/new_allocator.h:124
#8  0x000114e4 in std::list<std::shared_ptr<A>, std::allocator<std::shared_ptr<A> > >::_M_erase (this=0x23008, __position=...)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/stl_list.h:1573
#9  0x0001107c in std::list<std::shared_ptr<A>, std::allocator<std::shared_ptr<A> > >::remove (this=0x23008, __value=...)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/list.tcc:254
#10 0x00010ca0 in A::Delete (this=0x23008) at test_delete.cpp:23
#11 0x00010d64 in main () at test_delete.cpp:35

第二次:

(gdb) where
#0  A::~A (this=0x23008, __in_chrg=<optimized out>) at test_delete.cpp:28
#1  0x00011db4 in std::_Sp_counted_ptr<A*, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=0x23048)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/shared_ptr_base.h:290
#2  0x0001122c in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x23048)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/shared_ptr_base.h:144
#3  0x00010f3c in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0xbefffcb4, __in_chrg=<optimized out>)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/shared_ptr_base.h:546
#4  0x00010e44 in std::__shared_ptr<A, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0xbefffcb0, __in_chrg=<optimized out>)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/shared_ptr_base.h:781
#5  0x00010e70 in std::shared_ptr<A>::~shared_ptr (this=0xbefffcb0, 
    __in_chrg=<optimized out>)
    at /toolchain/arm-linux-4.8.2/arm-linux-gnueabi/include/c++/4.8.2/bits/shared_ptr.h:93
#6  0x00010cac in A::Delete (this=0x23008) at test_delete.cpp:23
#7  0x00010d64 in main () at test_delete.cpp:35


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值