我有两个shared_ptr
指向相同的int
,即在它们上面调用get()
会返回相同的地址。但是对它们调用use_count()
会返回1
。当它们中的最后一个超出范围时,它会尝试释放已经被另一个释放的内存,从而导致双重释放运行时错误:
#include <memory>
#include <iostream>
using namespace std;
int main() {
shared_ptr<int> sp1(make_shared<int>(7));
shared_ptr<int> sp2(&(*sp1));
cout << sp1.use_count() << endl; // 1
cout << sp2.use_count() << endl; // 1
cout << sp1.get() << endl; // same address
cout << sp2.get() << endl; // same address
}
// ^ Double free runtime error at closing brace.
在此变体中使用显式声明的原始指针发生同样的事情:
int main() {
int *raw_ptr = new int(8);
shared_ptr<int> sp3(raw_ptr);
shared_ptr<int> sp4(raw_ptr);
cout << sp3.use_count() << endl; // 1
cout << sp4.use_count() << endl; // 1
cout << sp3.get() << endl; // same address
cout << sp4.get() << endl; // same address
}
// ^ Double free runtime error at closing brace.
如果use_count()
两个1
指向相同的东西,为什么2
会返回shared_ptr
(但不会use_count()
}?如果1
返回int
,那么为什么尝试将shared_ptr
两次释放?我认为use_count
会shared_ptr
增加std::shared_ptr
当且仅当它指向与其兄弟use_count
s相同的地址时。
shared_ptr
的{{1}}仅由第一个shared_ptr
构造的原始指针(或对原始指针的赋值,如果是默认构造的)增加,然后由附加{增加{1}}'先前shared_ptr
的复制构造或作业?如果有的话,还有其他增量方法是什么?
答案 0 :(得分:6)
当您指向shared_ptr
时,该共享指针将获得该指针的所有权。您不再被允许delete
,将其传递给另一个shared_ptr
或类似内容。新的shared_ptr
没有全局查找表来检查是否已经拥有指针或类似内容的另一个shared_ptr
。
换句话说,通过传入相同的指针而不是复制shared_ptr
本身(增加使用次数)来创建第二个shared_ptr
时发生双重自由错误。直到稍后才能观察到未定义的行为这一事实不会改变实际发生的位置。
答案 1 :(得分:1)
您应该使用shared_ptr的复制构造函数来正确构造第二个共享指针。