shared_ptr 空值和自定义删除器的奇怪之处
shared_ptr strangeness with null values and custom deleter
我们最近在使用自定义删除器从 unique_ptr 移动到 shared_ptr 时遇到了崩溃。当用于创建智能指针的指针为空时发生崩溃。下面是重现问题的代码,并显示了两个有效的案例。
在下面的源代码中,一和二 运行 很开心,而三在 "ReleaseDestroy" 中崩溃了。当智能指针中使用的 class 具有虚拟 "Release" 时,崩溃似乎正在发生,因此程序正在尝试查找 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
不行,你的删除器也不行(因为它无条件取消引用 r
)。
顺便说一句,这在 LWG 2415, which addresses constructing a shared pointer from a unique pointer, which was broken before that defect resolution for exactly that reason. (I hit this problem myself here 中出现了;请注意该代码如何小心区分 shared_ptr
的 null 大小写。)
我们最近在使用自定义删除器从 unique_ptr 移动到 shared_ptr 时遇到了崩溃。当用于创建智能指针的指针为空时发生崩溃。下面是重现问题的代码,并显示了两个有效的案例。
在下面的源代码中,一和二 运行 很开心,而三在 "ReleaseDestroy" 中崩溃了。当智能指针中使用的 class 具有虚拟 "Release" 时,崩溃似乎正在发生,因此程序正在尝试查找 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
不行,你的删除器也不行(因为它无条件取消引用 r
)。
顺便说一句,这在 LWG 2415, which addresses constructing a shared pointer from a unique pointer, which was broken before that defect resolution for exactly that reason. (I hit this problem myself here 中出现了;请注意该代码如何小心区分 shared_ptr
的 null 大小写。)