【问题标题】:unique_ptr .release & .reset unexpected deleter behaviorunique_ptr .release & .reset 意外删除行为
【发布时间】:2014-09-15 23:39:41
【问题描述】:

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

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

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 上运行删除程序,而 .reset 在两个 unique_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

对于为什么这种行为出乎意料(或者更确切地说为什么我应该期待它)的任何意见,我将不胜感激。

谢谢!

【问题讨论】:

    标签: c++ unique-ptr


    【解决方案1】:

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

    调用release() 并不是在错误的unique_ptr 实例上运行删除程序,而是它没有在您调用release() 的实例上运行删除程序。另一个实例的删除器由unique_ptr 的析构函数自动调用,该析构函数由您的类的析构函数隐式调用。

    如果您不理会unique_ptr 实例,并且既没有对它们中的任何一个调用reset() 也没有调用release(),那么当您的类的析构函数执行时,您将看到预期的行为。

    【讨论】:

      【解决方案2】:

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

      所以在你的情况下调用release() 只会导致内存泄漏。

      【讨论】:

        猜你喜欢
        • 2017-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-27
        • 1970-01-01
        相关资源
        最近更新 更多