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 の開発者は、共有所有権のスマート ポインターを正しく実装するのが非常に難しいことに気付きました。他の人も同じ観察をしています。たとえば、Scott Meyers [Meyers01] は次のように述べています。

「STL自体には参照カウントスマートポインターが含まれておらず、常に正しく機能する優れたポインターを作成することは、必要がない限りやりたくないほどトリッキーです。参照用にコードを公開しました。 - 1996 年に、より効果的な C++ でスマート ポインターを数え、確立されたスマート ポインターの実装に基づいて、経験豊富な開発者による広範な公開前レビューに提出したにもかかわらず、有効なバグ レポートの小さなパレードが何年にもわたって少しずつ入ってきました。参照カウント スマート ポインターが失敗する可能性のある方法は注目に値します。」

これが宿題である場合は、swap()(メンバー) 関数を使用してコピー ctor と代入演算子を実装する方法について読んでください。それ以外の場合は、独自のスマート ポインターを作成しようとしないでください。勝つことはできません

于 2009-12-03T15:12:07.820 に答える
1

リークも見られませんが、他にもいくつかの問題があると思います(多くのコンパイラエラー以外に-これはあなたが使用しているコードではありません):

SmartPtr& operator=(SmartPtr& other)

const 参照によって引数を取る必要があります。同じ参照カウント インスタンスを共有するため、const 以外の左側で実行できるため、other の参照カウントをインクリメントする必要はありません。

次に、そのようなクラスの割り当てを実装する標準的な方法は、コピー アンド スワップ イディオムを使用することです。つまり、単純なスワップ メソッド (ポインターを交換するだけ) も定義する必要があり、自己割り当てについて心配する必要はありません :)

于 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 に答える