3

我有两个shared_ptrs 指向同一个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.

如果两个s 都指向同一个东西,为什么use_count()返回1(而不是)?如果返回,那么为什么要尝试释放两次?我认为 a当且仅当它指向与它的兄弟s相同的地址时才会增加一。2shared_ptruse_count()1intshared_ptruse_countshared_ptr

a 是否仅由 first由原始指针构造(或分配给原始指针,如果默认构造)然后通过附加s std::shared_ptr'复制构造或任何先前s 分配来增加?如果有的话,还有哪些其他的递增方式?use_countshared_ptrshared_ptrshared_ptr

4

2 回答 2

6

当您将指针指向 ashared_ptr时,该共享指针将拥有该指针的所有权。你不再被允许,将delete它传递给另一个shared_ptr,或类似的。没有全局查找表供新人shared_ptr检查以发现已经有另一个人shared_ptr已经拥有指针或类似的东西。

换句话说,当第二个shared_ptr是通过传入相同的指针而不是复制shared_ptr自身(这会增加使用计数)来创建时,就会发生双重释放错误。直到稍后您才能观察到未定义的行为这一事实不会改变它实际发生的位置。

于 2014-11-05T22:02:55.893 回答
1

您应该使用 shared_ptr 的复制构造函数来正确构造第二个共享指针。

于 2014-11-05T22:02:52.040 回答