Недавно мы столкнулись с сбоем при переходе от unique_ptr к shared_ptr с использованием пользовательского делетера. Авария произошла, когда указатель, используемый для создания умного указателя, был нулевым. Ниже приведен код, который воспроизводит проблему, и показывает два случая, которые работают.
В приведенном ниже источнике One и Two работают счастливо, а три аварии в "ReleaseDestroy". Сбой, похоже, происходит, когда класс, используемый в интеллектуальном указателе, имеет виртуальную "Release", поэтому программа пытается найти V-таблицу. 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();
}