【发布时间】:2014-11-05 21:59:41
【问题描述】:
我有两个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.
如果shared_ptrs 都指向同一个东西,为什么use_count() 会返回1(而不是2)?如果use_count() 返回1,那么为什么要尝试释放int 两次?我认为shared_ptr 将增加一个use_count 当且仅当它指向与其兄弟shared_ptrs 相同的地址。
是 std::shared_ptr 的 use_count 仅由原始指针构造的第一个 shared_ptr 递增(或分配给原始指针,如果默认构造),然后是额外的 shared_ptrs 复制-由任何先前的shared_ptrs 建造或分配?如果有的话,还有哪些其他的递增方式?
【问题讨论】:
-
试试
shared_ptr<int> sp4 = sp3;。您需要复制共享指针对象本身;使用相同的原始指针创建一个新的共享指针仅意味着现在您有两个共享指针,每个共享指针都认为它们拥有对象的独占所有权。如果你改为使用shared_ptr<int> sp3(new int(8));,这会更容易——不要让原始指针在你的程序中可见,以避免意外使用它。 -
实际上,
auto sp3 = std::make_shared<int>(8);更好,因为这允许 C++ 实现在单个内存分配中为int和shared_ptr控制块分配空间。 (标准不要求这种优化,但确实允许。如果你使用shared_ptr<int>(new int(8)),那么这种优化是不可能的。) -
@cdhowie,好点子。我在这里的评论只是为了让其他人更清楚,如果做
shared_ptr<int> sp3(new int(8)); shared_ptr<int> sp4(new int(8));、sp3和sp4指向不同的ints(在不同的地址),它们只是具有相同的值。
标签: c++ pointers memory-management shared-ptr double-free