我有一个显然被双重删除的对象,尽管被智能指针跟踪。我是使用智能指针的新手,所以我做了一个简单的函数来测试我是否正确使用了对象。
int *a = new int(2);
std::shared_ptr<int> b(a);
std::shared_ptr<int> c(a);
主函数中的这组行导致运行时错误,因为指针超出范围,为什么?是不是智能指针应该能够自己处理a的删除?
答案 0 :(得分:9)
shared_ptr
期望拥有指向的对象。
您所做的就是创建两个单独的智能指针,每个智能指针都认为它拥有底层int
的独占所有权。他们不了解彼此的存在,他们不会互相交谈。因此,当它们超出范围时,两个指针都会删除底层资源,结果很明显。
当您创建shared_ptr
时,它会创建一种&#34;管理对象&#34;这是资源的生命周期。当您复制一个shared_ptr
时,两个副本都引用相同的管理对象。管理对象跟踪有多少shared_ptr
个实例指向此资源。 int*
本身没有这样的&#34;管理对象&#34;,因此复制它不会跟踪引用。
这里是对代码的最小重写:
// 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*
上的引用数量会减少,并且当最后一个引用进入时,对象将被删除。
答案 1 :(得分:2)
您只能从原始指针创建一次智能指针。所有其他共享指针必须是第一个的副本才能使它们正常工作。更好的是:使用make shared:
std::shared_ptr<int> sp1 = std::make_shared<int>(2);
std::shared_ptr<int> sp2 = sp1;
编辑:忘了添加第二个指针
答案 2 :(得分:0)
正确用法是:
std::shared_ptr<int> b = std::make_shared<int>(2);
std::shared_ptr<int> c = b;