首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么可以将一个指针放在unique_ptr的向量中两次?

为什么可以将一个指针放在unique_ptr的向量中两次?
EN

Stack Overflow用户
提问于 2021-04-07 06:42:55
回答 2查看 104关注 0票数 1

难道std::unique_ptr不应该防止出现这样的错误吗?

代码语言:javascript
复制
#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";

}

检测到双重释放时的错误消息:

代码语言:javascript
复制
*** 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
...             

忽略双重释放时的输出:

代码语言:javascript
复制
p:0x1094c20
v[0]:0x1094c20
p:0x1094c20
v[1]:0x1094c20
EN

回答 2

Stack Overflow用户

发布于 2021-04-07 06:56:41

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

  • 永远不要创建拥有的原始指针;使用return std::unique_ptr<Base>(new Derived(...));
  • Do您必须绝对使用std::unique_ptr创建拥有的原始指针(即,为了从工厂函数调用私有构造函数),然后在立即将原始指针包装在std::unique_ptr中而不做其他任何操作的语句中创建拥有的原始指针,例如,不要使用在任何其他上下文中采用原始指针的std::unique_ptr构造函数。

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

票数 6
EN

Stack Overflow用户

发布于 2021-04-07 07:31:50

最小示例(不需要vector):

代码语言:javascript
复制
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放入容器中并不会改变这一点。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66977380

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档