1

したがって、これは少し概念的な質問です。私は C++ で LinkedList を作成しています。Java が私の最初の言語であるため、removeAll 関数を作成して、ヘッド ノードとテール ノードを結合するだけです (センチネル ノードを使用しています)。しかし、ノード用にメモリを解放する必要があるため、これは C++ では機能しないことにすぐに気付きます。

すべての要素を手動で削除して、リスト全体を反復処理する方法はありますか?

4

3 に答える 3

7

各ノードに次のノードを所有させることができます。つまり、それ自体が破棄されたときにそのノードを破棄する責任があります。これは、次のようなスマート ポインターを使用して行うことができますstd::unique_ptr

struct node {
    // blah blah
    std::unique_ptr<node> next;
};

次に、最初のノードを破棄するだけで、他のすべてのノードが考慮されます。それらはすべて、unique_ptr デストラクタの連鎖反応で破棄されます。

ただし、これが双方向にリンクされたリストである場合はunique_ptr、両方向に s を使用しないでください。これにより、各ノードが次のノードを所有し、次のノードによって所有されます! この所有関係は一方向にのみ存在するようにする必要があります。他の使用では、通常の非所有ポインターを使用します。node* previous;

ただし、センチネル ノードの場合、これはそのままでは機能しません。破棄しないでください。これを処理する方法は、センチネル ノードの識別方法とリストのその他のプロパティによって異なります。

たとえば、ブール値のメンバーをチェックするなど、センチネル ノードを簡単に区別できる場合は、センチネルの削除を回避するカスタム デリーターを使用できます。

struct delete_if_not_sentinel {
    void operator()(node* ptr) const {
        if(!ptr->is_sentinel) delete ptr;
    }
};

typedef std::unique_ptr<node, delete_if_not_sentinel> node_handle;

struct node {
    // blah blah
    node_handle next;
};

これにより、センチネルでの連鎖反応が停止します。

于 2012-08-23T02:15:29.747 に答える
1

c ++ガベージコレクターを使用すれば、Javaのようにそれを行うことができます。多くはありません。いずれにせよ、リスト内の各要素を割り当てるためのコストを費やすため、実行時間の一定の要素を節約できます。

于 2012-08-23T02:04:33.807 に答える
0

はい。まあ、一種の...メモリプールを使用するようにリストを実装すると、そのプール内のすべてのデータを担当し、メモリプールを削除することでリスト全体を削除できます(1つ以上の大きなメモリチャンクが含まれる場合があります) )。

メモリ プールを使用する場合、通常、次の考慮事項の少なくとも 1 つがあります。

  • オブジェクトの作成方法と破棄方法の制限。
  • 保存できるデータの種類に関する制限。
  • 各ノードでの追加のメモリ要件 (プールを参照するため)。
  • シンプルで直感的なプールと、複雑で紛らわしいプールです。

私はこれについて専門家ではありません。一般に、高速なメモリ管理が必要な場合は、メモリが一度読み込まれ、空きリストなどを維持する必要がありません。特定の目標と設計上の制約がある場合、メモリ プールの設計と実装ははるかに簡単です。すべての状況で機能する魔法の弾丸が必要な場合は、おそらく運が悪い.

于 2012-08-23T02:14:35.270 に答える