加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – shared_ptr具有空值和自定义删除的陌生人

发布时间:2020-12-16 06:43:23 所属栏目:百科 来源:网络整理
导读:我们最近在使用自定义删除器从unique_ptr转到shared_ptr时遇到了一个崩溃.当用于创建智能指针的指针为空时,发生崩溃.以下是重现问题的代码,并显示两种情况. 在下面的源代码中,One和Two运行愉快,而“ReleaseDestroy”中的三个崩溃.当智能指针中使用的类具有虚
我们最近在使用自定义删除器从unique_ptr转到shared_ptr时遇到了一个崩溃.当用于创建智能指针的指针为空时,发生崩溃.以下是重现问题的代码,并显示两种情况.

在下面的源代码中,One和Two运行愉快,而“ReleaseDestroy”中的三个崩溃.当智能指针中使用的类具有虚拟“释放”时,崩溃似乎正在发生,因此程序正在尝试查找V-Table. unique_ptr看起来像检查空指针并且不运行析构函数.共享指针似乎忽略了这一点.

有人知道这是否是设计,还是stl实现中的错误?我们正在使用Visual Studio 2015.

#include <iostream>
#include <memory>

template<class R>
void ReleaseDestroy(R* r)
{
    r->Release();
};

class FlatDestroy
{
public :
    void Release()
    {
        delete this;
    }
};

class VirtualDestroy
{
public:
    virtual void Release()
    {
        delete this;
    }
};

class SimpleOne
{
public :
};

void main()
{
    std::shared_ptr<SimpleOne> One(nullptr);
    std::shared_ptr<FlatDestroy> Two(nullptr,ReleaseDestroy<FlatDestroy>);
    std::shared_ptr<VirtualDestroy> Three(nullptr,ReleaseDestroy<VirtualDestroy>);

    One.reset();
    Two.reset();
    Three.reset();
}

解决方法

unique_ptr和shared_ptr的销毁行为是不同的:

> unique_ptr只有在被保持的指针不为空的情况下才调用它.
> shared_ptr总是调用删除器.

所以你的共享指针删除器必须能够处理空指针值!例如,std :: free是好的,但是std :: fclose不是,你的删除者也不是(因为它无条件地引用).

顺便说一下,这个在LWG 2415年出现,它解决了从一个唯一的指针构建一个共享指针,这个指针在那个缺陷解决之前被破坏了. (我自己打了这个问题here;请注意该代码如何小心区分shared_ptr的null大小写.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读