2

C ++の組み込みポインターを操作しているときに、問題が発生しました。プログラムが終了すると、クラスのデストラクタがすべて呼び出されます。私はデータクラス、キュークラスを持っており、組み込みの別のデータクラスは次のようにキューを使用します(その場で大まかなコーディングに注意してください)。

class Data {
  int x;
}

class Queue {
  class Node {
    Data* x;
  }
  Node* head;
}

class C1 {
  Queue q;
}

class C1Queue{
  class Node {
    C1* c;
  }
  Node* head;
}

オブジェクトに存在しない別のキューq2もあります。私はファイルから両方のキューをロードするので、(cQueueがC1Queueであると仮定して)次のように言います。

Data *d = new Data(0);
q2->pushBack(d);
C1 c = new C1();
cQueue->pushBack(c->pushBack(d));

ご覧のとおり、各データへのポインターを保持するキュー(q2)と、q2が保持しているのと同じデータへのポインターを保持するキューを持つオブジェクトの両方があります。これで、プログラムが終了したときに、すべてのデータの割り当てを解除する必要があります。ただし、オブジェクトの割り当てが解除されると、最初にq2の割り当てが解除され、C1オブジェクトの割り当てが解除されると、キューの割り当てが解除されます。これにより、削除されたばかりのq2と同じデータが削除されます。または、オブジェクトが最初に割り当て解除され(どの順序が発生するかはわかりません)、次にq2の割り当てが解除され、すでに削除されたメモリにぶつかる場合もあります。

したがって、問題はメモリスペースが2回削除されていることですが、これは良くありません。メモリが削除されると、他のプログラムに解放されて使用されるため、そのメモリスペースを再度削除すると、セグメンテーション違反が発生します。

ここで何かが足りないかもしれませんが、特別な種類のポインターがないと、これを行う方法がわかりません(特別な種類のポインターは使用できません)。

私が考えることができる唯一の方法は、C1オブジェクトがキューの割り当てを解除するのをブロックし、残りのオブジェクトの割り当てを解除することですが、その方法がわかりません。誰かがこれを手伝ってくれるなら、私はそれを大いに感謝します。

4

1 に答える 1

1

のような細心の注意を払うことは (明らかに) 禁止されているstd::shared_ptrため、次の 3 つの解決策のいずれかを試すことができます。

  • 手動参照カウント。a がキューにプッシュされるたびDataにその refcount がインクリメントされ、 aQueueがクリーンアップされると refcount が減らされることを強制します。refcount がゼロになったとき(ただし、常にヒープに s をdelete this割り当てるようにしてください!)Data
  • Data要素を「所有」するオブジェクトを指定します。そのオブジェクトだけが破棄できDataます (プライベート デストラクタとフレンド クラスを使用してこれを強制することもできます)。これらが複数必要になる場合があります。(このプロキシを refcount すると、これは貧乏人の になりますstd::shared_ptr)。
  • あなたDataの をコピー可能にして、真新しいオブジェクトですべてを実行してください。これは、同期を維持する必要のない少量のデータ (たとえば、Point2D2 つの整数を保持するクラス) の場合に機能します。
于 2013-03-06T03:55:46.423 に答える