为什么可以在unique_ptr的向量中放置两次指针



std::unique_ptr不应该防止出现这种错误吗?

#include <iostream>
#include <vector>
#include <memory>
struct B {
int b;
};
int main()
{
std::vector<std::unique_ptr<B>> v;  // unique_ptr can be stored in a container
B* p = new B;
v.emplace_back(p);
std::cout << "p:" <<p <<"n";
std::cout << "v[0]:"<<v[0].get() << "n";
v.emplace_back(p);
std::cout << "p:" <<p <<"n";
std::cout << "v[1]:"<<v[1].get() << "n";
}

检测到双重空闲时的错误消息:

*** Error in `./a.out': double free or corruption (fasttop): 0x0000000001094c20 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f3da200b7e5]
...
======= Memory map: ========
00400000-00402000 r-xp 00000000 ca:01 3228321                            /tmp/1617748074.6996937/a.out
...             

忽略双自由时的输出:

p:0x1094c20
v[0]:0x1094c20
p:0x1094c20
v[1]:0x1094c20

std::unique_ptr如果使用得当,可以防止双重免费错误:

  • 永远不要创建拥有的原始指针;使用CCD_ 3
  • 如果您必须使用new(,即按顺序创建一个拥有的原始指针从工厂函数调用私有构造函数(,然后执行在一个语句中,该语句立即将原始指针包装在std::unique_ptr并且不做任何其他事情,例如return std::unique_ptr<Base>(new Derived(...));
  • 不要在任何其他上下文中使用接受原始指针的std::unique_ptr构造函数

如果遵循这些准则,每个unique_ptr将管理一个不由其他人管理的对象。如果不遵循它们,可能会出现类似您所观察到的错误,即可以从同一个原始指针创建多个unique_ptr实例。两个实例都不是";意识到";您传递给它的原始指针已经由另一个实例拥有。如果unique_ptr构造函数必须检查是否有其他人拥有该指针,这将为每个用户带来性能开销。我们使用C++来避免这种不必要的开销。只要你遵循指导原则,这是没有必要的。

最小示例(不需要vector(:

struct B {
int b;
};
int main()
{
B* p = new B;
std::unique_ptr<B> x(p);
std::unique_ptr<B> y(p);
}

您有两个unique_ptr,他们认为自己拥有相同的原始指针。他们都会在那个指针上调用delete,你会得到一个双自由。将unique_ptr放入容器中并不能改变这一点。

最新更新