shared_ptr奇怪性与空值和自定义删除

时间:2017-03-14 01:56:39

标签: c++ shared-ptr unique-ptr

我们最近在使用自定义删除工具从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();
}

1 个答案:

答案 0 :(得分:13)

unique_ptrshared_ptr的破坏行为不同:

  • unique_ptr只有在保持指针非空时才调用删除器。

  • shared_ptr始终调用删除者。

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

顺便提一下,这会在LWG 2415中出现,它解决了从唯一指针构建共享指针的问题,该指针在该缺陷解决之前就已被破解,正是出于这个原因。 (我自己解决了这个问题here;请注意该代码如何谨慎区分shared_ptr的空案例。)

相关问题