共享指针双删除

shared pointer double deleting

本文关键字:删除 指针 共享      更新时间:2023-10-16

我有一个对象,尽管被智能指针跟踪,但显然被双重删除了。我是使用智能指针的新手,所以我做了一个简单的函数来测试我是否正确使用了对象。

int *a = new int(2);
std::shared_ptr<int> b(a);
std::shared_ptr<int> c(a);

main函数中的这组行会导致运行时错误,因为指针超出了作用域,为什么?难道智能指针不应该能够自己处理a的删除吗?

shared_ptr期望拥有指向的对象。

您所做的是创建两个独立的智能指针,每个智能指针都认为它对底层int具有独占所有权。他们不知道彼此的存在,也不互相交谈。因此,当它们超出作用域时,两个指针都会删除底层资源,结果很明显。

创建shared_ptr时,它创建了一种"管理对象",负责资源的生命周期。当您复制 shared_ptr时,两个副本引用相同的管理对象。管理对象跟踪指向该资源的shared_ptr实例的数量。int*本身没有这样的"管理对象",因此复制它不会跟踪引用。

下面是对代码的最小重写:

// incidentally, "make_shared" is the best way to do this, but I'll leave your
// original code intact for now.
int *a = new int(2);
std::shared_ptr<int> b(a);
std::shared_ptr<int> c = b;

现在,它们都引用相同的底层管理对象。当每个shared_ptr被销毁时,int*上的引用数量减少,当最后一个引用消失时,该对象被删除。

您只允许从原始指针制作一次smartpointer。所有其他共享指针必须是第一个指针的副本,以便它们能够正确工作。甚至更好:使用make shared:

 std::shared_ptr<int> sp1 = std::make_shared<int>(2);
 std::shared_ptr<int> sp2 = sp1;

编辑:忘记添加第二个指针

正确的用法是:

std::shared_ptr<int> b = std::make_shared<int>(2);
std::shared_ptr<int> c = b;