当原始指针和唯一指针都引用同一个对象时,如何避免双重释放?

Posted

技术标签:

【中文标题】当原始指针和唯一指针都引用同一个对象时,如何避免双重释放?【英文标题】:How to avoid double freeing when raw pointer and unique pointer both refer to the same object? 【发布时间】:2019-07-21 18:25:32 【问题描述】:

在下面的代码中,x(原始指针)和p(唯一指针)都指向变量a;所以值“a”的变化反映了两个指针的取消引用。我知道“p”拥有&a的所有权。我试图理解指针超出范围时的行为,哪个指针首先被释放?我怎样才能避免双重释放?

#include <iostream>
#include <memory>

int main() 
    int a = 5;

    int *x = &a;
    std::unique_ptr<int> p(&a);

    *p = 6;
    std::cout<< *x << *p <<'\n';
    // prints 66
    *x =7;
    std::cout <<*x <<*p <<"\n";
    // 77

    std::cout  << "Done!"<<'\n';

附:我收到此运行时错误“未分配被释放的指针”

【问题讨论】:

您不能将std::unique_ptr 与分配在堆栈上的对象一起使用(好吧,除非您提供自定义的释放器,它对对象没有任何作用)。你为什么要这么做? 您的代码中没有双重免费。普通指针在销毁时不会释放任何东西。 @melpomene 他正在从一个自动变量的地址构造一个unique_ptr。当自动和unique_ptr 都被销毁时,导致问题。 "我知道“p”拥有 &a 的所有权。" 嗯,它试图这样做,但它确实不能。 a 已经拥有自己;你不能把它拿走。 “我知道“p”拥有 &a 的所有权——不,你错了。 unique_ptr 不能取得自动变量的所有权。你需要回去重新阅读你的 C++ 书籍。 【参考方案1】:

std::unique_ptr&lt;int&gt; p(&amp;a); 只是一个错误,因为a 是一个自动变量,当它超出范围时将被销毁。而您刚刚创建了一个unique_ptr尝试销毁同一个对象的情况。只是不要那样做。

您似乎认为,如果您将unique_ptr 形成为现有对象,那么新的unique_ptr 将拥有该对象的独占所有权。这是错误的。

还有;原始指针在销毁时不会删除它们指向的内容。这与您的原始指针无关

【讨论】:

以上是关于当原始指针和唯一指针都引用同一个对象时,如何避免双重释放?的主要内容,如果未能解决你的问题,请参考以下文章

保持对唯一指针引用的唯一指针引用

引用还是指针?

使用唯一指针将节点添加到树

将全局数组复制到由双指针引用的数组中

测试数据时如何避免空指针异常

在 GDB 中取消引用双指针(指向值的指针)