【问题标题】:Catching a memory leak in a shared pointer?在共享指针中捕获内存泄漏?
【发布时间】:2013-08-25 08:18:53
【问题描述】:

标题几乎说明了一切,我几乎肯定它在复制构造函数或赋值运算符中,我很确定是后者。这是一个非常短的课程,所以我会发布整个内容,任何关于如何处理它的建议都会很好。老实说,我在这里也有点过头了,所以任何指向一些扎实的阅读的人都将不胜感激。

#pragma once

//for non-learning purposes, boost has a good smart pointer
template <class type>
class sPtr
{
private:
    type *p;
    int r; //referenceCount

    void add()
    {
        r++;
    }
    int release()
    {
        return --r;
    }
public:
    sPtr(): p(NULL), r(1) {}
    sPtr(type *pValue): p(pValue)
    {
        add();
    }
    sPtr(const sPtr<type> & sp): p(sp.p), r(sp.r)
    {
        add();
    }
    ~sPtr()
    {
        if(release() == 0)
        {
            delete p;
        }
    }

    type* get()
    {
        return p;
    }

    type& operator*()
    {
        return *p;
    }
    type* operator->()
    {
        return p;
    }
    sPtr<type>& operator=(sPtr<type> sp)
    {
        std::swap(this->p, sp.p);
        std::swap(this->r, sp.r);
        add();

        return *this;
    }
};

我很确定赋值运算符应该通过引用传递,但我不确定这将如何影响实现。我尝试了几种不同的实现,但它们都仍然存在泄漏。

【问题讨论】:

    标签: c++ memory-leaks shared-ptr assignment-operator


    【解决方案1】:

    您的每个共享指针都会跟踪自己的单独引用计数。这显然不好。当一个被销毁时,其他的引用计数不会更新。您需要将引用计数保存在所有共享指针都可以访问的单独位置。

    【讨论】:

    • 它需要对智能指针类进行相对较大的重写,但我终于让它工作了。感谢您的提示,没有它就无法做到。
    【解决方案2】:

    除了 Ben 已经提到的之外,您在默认构造函数中从 1 开始引用计数(并且在其他构造函数中根本没有初始化它)。如果您在默认构造函数之后为其分配一个指针,您的引用计数将为 2,当您调用 release 时,返回 1。简而言之,您的引用计数唯一一次为 0(表示您可以删除该对象)是如果您调用 release 1 的时间比调用 add 的时间多。通常,您希望这些调用是对称的(添加调用对应于释放调用)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-13
      • 2023-03-15
      • 1970-01-01
      • 2013-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-26
      相关资源
      最近更新 更多