关于 c++的智能指针析构2次的问题

我正在学习c++的智能指针这一块。看了很多帖子,据说这样的程序会引起2次析构对象。但是我这里程序运行一切正常。这个怎么解释?谢谢大家!(系统:centos 7, g++版本:4.8.5)
clipboard.png

clipboard.png

阅读 8.2k
2 个回答

那是因为你最后没有delete b这个指针. 在 堆(heap) 中分配的内存指针需要delete, 否则可能会造成内存泄漏.
智能指针会自动释放该对象的指针. 所以再次 delete 会销毁两次.
所以,不要混用智能指针和普通指针.

槽点1:

BaseClass *b = new BaseClass();
std::shared_ptr<BaseClass> test(b->getInstance());

这是bad practice, 虽然还不是UB, 但是只有一步之遥了, 比如加一个std::shared_ptr<BaseClass> test2(b->getInstance());double delete了.

解决方法:

所以第一步要做的是把BaseClass *b = new BaseClass();修改成std::shared_ptr<BaseClass> b(new BaseClass);

到此结束了吗? 不, 继续噗:

槽点2:

  std::shared_ptr<BaseClass> getInstance()
  {
      return std::shared_ptr<BaseClass>(this);
  }
  

假设已经做出上述修改了, 由于上段代码的存在, 依旧会杯具. 原因和上面类似, 因为test并不知道this已经被b用过了, 所以引用计数就gg了. 你需要自己实现一个shared_ptr就能理解了.

解决方法:

使用std::enable_shared_from_this:

class BaseClass :  enable_shared_from_this<S>
{
public:
  BaseClass(){cout << "BaseClass construct" << endl;}
  ~BaseClass(){cout << "Base destructor" << endl;}
  std::shared_ptr<BaseClass> getInstance()
  {
      return shared_from_this();
  }
};

想进一步了解可以去看enable_shared_from_this是如何实现的.

槽点3:

不存在disconstruct这种说法, 跟我念: destructor

槽点4:

永远不要贴截图(qq群里也一样, 不通过markdown就用paste.ubuntu.

懒得打字这次我给你输好了, 请贴近问题描述中:

#include <iostream>
#include <memory>
using namespace std;
class BaseClass;
class ChildClass;
typedef std::shared_ptr<BaseClass> BaseClassPtr;
typedef std::shared_ptr<ChildClass> ChildClassPtr;
class BaseClass
{
public:
  BaseClass(){cout << "BaseClass construct" << endl;}
  ~BaseClass(){cout << "Base destructor" << endl;}
  std::shared_ptr<BaseClass> getInstance()
  {
      return std::shared_ptr<BaseClass>(this);
  }
};
int main()
{
    BaseClass *b = new BaseClass();
    std::shared_ptr<BaseClass> test(b->getInstance());
    cout << "end" << endl;
}

槽点5:

你应该把这段代码的链接发出来, 一方面展示自己从哪里获取的信息, 一方面挺想看是谁写出这样的代码的.

槽点6:

这是针对另一位答主的, 语言没有规定是heap, 只说了是free store. 具体可以参见帝球此贴

槽点7:

这是一个c++的问题, 不要贴c的标签, 完全两门不搭界的语言.

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题