unique_ptr .release& .reset意外删除行为

时间:2014-09-15 23:39:41

标签: c++ unique-ptr

我正在尝试使用智能指针并遇到unique_ptr的问题。引发这种情况的是,在VS2013中,我在类析构函数中使用.release()并且它没有释放(使用TRACE)但它与.reset一致。 我在以下网址上有一些示例代码:IDEOne Example Code

我创建了一个包含两个unique_ptr成员的类。这些成员在构造函数中被赋值,理论上,根据我理解的智能指针理论,它应该自动获得delete d。它们被分配了一个自定义结构作为自定义删除器,如下所述:

struct Deleter
    {
    void operator()(TCHAR* p) const
    {
        std::cout << "Deleter deleting .." << p << '\n';
        delete[] p;
    }
};

unique_ptr成员被声明为:

unique_ptr<TCHAR[], Deleter> szMySimpleString;
unique_ptr<TCHAR[], Deleter> szMySimpleStringLeak;

然后在类的构造函数中将unique_ptr成员定义为:

    szMySimpleString = unique_ptr<TCHAR[], Deleter>(new TCHAR[255], Deleter());
    szMySimpleStringLeak = unique_ptr<TCHAR[], Deleter>(new TCHAR[255], Deleter());
    strcpy(this->szMySimpleString.get(), "szMySimpleString");
    strcpy(this->szMySimpleStringLeak.get(), "szMySimpleStringLeak");

删除此类后,我的析构函数在一个示例中运行.release(),在另一个示例中运行.reset()。每个人都有我不希望的行为。 .release()正在错误unique_ptr上运行删除工具,而.resetunique_ptr上运行删除工具。

请在此问题开头的链接中查看完整代码(注意:有3个注释区域可以一次运行一个以查看每个效果)。

如果我跑:

szMySimpleStringLeak.release();

我得到了结果:

    Doing Stuff ...
    Contents of szMySimpleString: szMySimpleString
    Contents of szMySimpleStringLeak: szMySimpleStringLeak

    MyStupidClass Destructor running...
    Deleter deleting ..szMySimpleString

如果我跑:

szMySimpleString.release();

我得到了结果:

Deleter deleting ..szMySimpleStringLeak

如果我跑:

szMySimpleString.reset();

我得到了结果:

    MyStupidClass Destructor running...
    Deleter deleting ..szMySimpleString
    Deleter deleting ..szMySimpleStringLeak

我很感激为什么这种行为是出乎意料的(或者更确切地说,为什么我应该期待它)。

谢谢!

2 个答案:

答案 0 :(得分:4)

unique_ptr::release放弃托管对象的所有权而不破坏托管对象。 unique_ptr::reset将使用提供的删除器销毁对象。

并非调用release()正在错误的unique_ptr实例上运行删除程序,而是它没有在您调用release()的实例上运行删除程序unique_ptr 1}}。另一个实例的删除器由unique_ptr的析构函数自动调用,这个析构函数由您的类隐式调用&#39;析构函数。

如果您单独留下reset()个实例,并且未对其中任何一个调用release()或{{1}},那么当您的班级&#39;时,您会看到预期的行为。析构函数执行。

答案 1 :(得分:1)

unique_ptr::release()不会删除内部指针,而是会释放它的所有权See the doc

因此,在您的情况下,调用release()只会导致内存泄漏。