1

我有小问题理解为什么我的智能指针类在自我评估时泄漏。如果我做这样的事情

SmartPtr sp1(new CSine());//CSine is a class that implements IFunction iterface
sp1=sp1;

我的同事告诉我,我的智能指针泄漏了。我在我的智能指针中添加了一些日志消息来跟踪正在发生的事情和测试并报告了这一点:

SmartPtr sp1(new CSine());
->CSine constructor
->RefCounter increment 0->1
->RefCounter constructor
->SmartPtr constructor

sp1=sp1;
->checks if this.RefCounter == to parameter.RefCounter, if true returns the smart pointer unmodified else modifies the object and returns it with the new values; in this case it returns true and returns the object unchanged.

at the end
->SmartPtr destructor
->RefCounter decrement 1->0
->RefCounter destructor
->CSine destructor

我不明白为什么他们认为我的智能指针泄漏了……有什么想法吗?先感谢您!

class SmartPtr
{
private:
    RefCounter* refCnt;
    void Clear()
    {
        if(!isNull() && refCnt->Decr() == 0)
            delete refCnt;
        refCnt = 0;
    };
public:
    explicit SmartPtr();
    explicit SmartPtr(IFunction *pt):refCnt(new RefCounter(pt)){};
    SmartPtr(SmartPtr& other)
    {
        refCnt = other.refCnt;
        if (!isNull())
            refCnt->Incr();
    };
    virtual ~SmartPtr(void){Clear();};

    SmartPtr& operator=(SmartPtr& other)
    {
        if(other.refCnt != refCnt)
        {
            if(!rVar.isNull())
                other.refCnt->Incr();
            Clear();
            refCnt = other.refCnt;
        }
        return *this;
    };

    SmartPtr& operator=(IFunction* _p)
    {

        if(!isNull())
        {
            Clear();
        }
        refCnt = new RefCounter(fct);
        return *this;
    };

    IFunction* operator->();
    const IFunction* operator->() const;
    IFunction& operator*();
    const IFunction& operator*() const;
    bool isNull() const { return refCnt == 0; };

    inline bool operator==(const int _number) const;
    inline bool operator!=(const int _number) const;
    inline bool operator==(IFunction* _other) const;
    inline bool operator!=(IFunction* _other) const;
    inline bool operator==(SmartPtr& _other) const;
    inline bool operator!=(SmartPtr& _other) const;
};

class RefCounter
{
    friend class SmartPtr;
private:
    IFunction* p;
    unsigned c;

    explicit RefCounter(IFunction* _p):c(0),p(_p)
    {
        if(_p != NULL)
            Incr();
        cout<<"RefCounter constructor."<<endl;
    }
    virtual ~RefCounter(void)
    { 
        cout<<"RefCounter destructor."<<endl;
        if(c == 0)
            delete p; 
    }
    unsigned  Incr()
    {
        ++c;
        cout<<"RefCounter increment count:"<<c-1<<" to "<<c<<endl;
        return c; 
    }
    unsigned  Decr()
    {
        if(c!=0)
        {
            --c;
            cout<<"RefCounter decrement count:"<<c+1<<" to "<<c<<endl;
            return c;
        }
        else
            return 0;
    }
};
4

6 回答 6

3
SmartPtr& operator=(SmartPtr& other)
    {
        if(rVar.refCnt != refCnt)

应该:

    if ( this != & other ) 
于 2009-12-03T14:52:58.763 回答
2

您可能希望查看A Proposal to Add General Purpose Smart Pointers to the Library Technical Report中的以下引用:

Boost 开发人员发现共享所有权智能指针极难正确实现。其他人也做出了同样的观察。例如,斯科特迈耶斯 [Meyers01] 说:

“STL 本身不包含引用计数智能指针,并且编写一个好的指针 - 一个始终正常工作的指针 - 非常棘手,除非你必须这样做,否则你不想这样做。我发布了代码以供参考- 在 1996 年在更有效的 C++ 中计算智能指针,尽管它基于已建立的智能指针实现并将其提交给有经验的开发人员进行广泛的预发布审查,但多年来仍有少量有效的错误报告。引用计数智能指针可能失败的方式非常显着。”

如果这是家庭作业,请阅读有关如何使用swap()(成员)函数实现复制 ctor 和赋值运算符的信息。否则,不要尝试编写自己的智能指针。你赢不了

于 2009-12-03T15:12:07.820 回答
1

我也没有看到泄漏,但我认为还有其他一些问题(除了许多编译器错误 - 这不可能是您正在使用的代码):

SmartPtr& operator=(SmartPtr& other)

应该通过 const 引用来获取参数。您不必增加其他的引用计数,因为您可以在非常量左侧执行此操作,因为它们将共享相同的引用计数实例。

接下来,为此类类实现赋值的规范方法是使用复制和交换习语——这意味着您还应该定义一个简单的交换方法(它只是交换指针),而不必担心自赋值:)

于 2009-12-03T15:47:05.850 回答
0

我的印象是没有内存泄漏。为了确定:

  • 使用 valgrind 或 VS-alternative 进行测试
  • 使用 std::tr1::shared_ptr (如果这不仅仅是教育)
于 2009-12-03T15:12:36.143 回答
0

您的代码无法编译,这让我相信您发布的版本不可能是您同事抱怨的版本。

于 2009-12-03T15:33:21.303 回答
-1

几乎任何智能指针都会有泄漏的情况。如果您使用引用实现它,这就是它必须的方式。还有一百万个其他问题,而且它们很慢。由于它们比原始指针更错误,因此如果您从中得到的只是引用计数,那么实际上并没有多大用处。我很想将它们用于一些非常特殊的目的,但它们不适用于一般编程用途。例如,在 STL 容器中不允许使用它们是有原因的。

于 2009-12-04T01:10:18.890 回答