0

別のオブジェクトへのポインタメンバーを保持するクラスがあるとしましょう。デストラクタでそのポインタを削除すると、エラーが発生します(理由はわかります)。

私の質問は:メモリリークなしでそれを克服することは可能ですか?

これが私がしていることのデモです。

class A {
    public:
    ~A() { cout<< "~A()" <<endl; }
};

class B {
    A *pA;
    public:
    B(A* pA) {
        this->pA = pA;
    }
    ~B() { 
                delete pA;
        cout<<"~B()"<<endl;
    }
};

int main() {
    A a;
    {
        B b2(new A()); //deletes A, deletes B, no memory leaks
    }
    {
        B b(&a); //deletes A, error.
    }

    return 0;
}
4

3 に答える 3

2

まず第一に、それはメモリリークではなく、未定義の動作であり、より深刻な問題です。間違った領域からメモリの割り当てを解除しようとしました。対応するでのみ
使用する必要があります。delete/delete[]/free()new/new[]/malloc()

完全な証明やアーキテクチャに依存しない方法はありません。優れたプログラミング手法に従うだけです。

常に完璧であるとは限りませんが、1つの方法は、同様のデータ構造をオーバーロードnewdeleteて保持することです。std::map呼び出されるたびnewに、ポインタを追加します。deleteポインタが存在するかどうか、割り当てがタイプなどであるかどうかを確認できますnew。これnew[]
間違いなくパフォーマンスに影響するため、デバッグモードのままにしておく必要があります。

于 2013-03-20T07:12:24.520 に答える
2

動的に割り当てられたオブジェクトを所有していると考えて、それを削除しようとする2つのオブジェクトがあります。解決策は、誰がオブジェクトを所有するかを決定し、適切なスマートポインターを使用して正しいコピー/割り当て動作を実装することです。

  1. 動的に割り当てられたオブジェクトを処理しますAか?B生のポインタからこれを知る方法はないので、どちらかのケースをカバーするように設計を修正する必要があります。動的オブジェクト割り当てを想定すると、
  2. 各オブジェクトは独自のコピーを所有しています。Aまたはの3つのルールを実装しB、2つのうち1つだけを削除します。スコープポインタを使用して、メモリ管理を簡素化できます(、、boost_scoped_ptrまたはstd::unique_ptr)。
  3. 一意の所有権:単一のオブジェクトがコピーを所有します:を使用しstd::unique_ptrます。コピーと代入を禁止し、ムーブコピーとムーブ代入を許可する
  4. 共有所有権:誰も/誰もがオブジェクトを所有していません。誰も参照しないと削除されます:usestd::shared_ptr
于 2013-03-20T07:15:01.293 に答える
1

Bポインタを所有している場合と所有していない場合を指定する必要があります。

いつ通知するフラグを追加します

class B {
    bool owner;
    A *pA;
    public:
    B(A* pA, bool bOwner) : owner(bOwner) {
        this->pA = pA;
    }
    ~B() { 
        if (owner)
            delete pA;
        cout<<"~B()"<<endl;
    }
};

int main() {
    A a;
    {
        B b2(new A(), true); //deletes A, destroys B, no memory leaks
    }
    {
        B b(&a, false); //destroys B, ok.
    }

    return 0;
}
于 2013-03-20T07:19:30.083 に答える