したがって、これは少し概念的な質問です。私は C++ で LinkedList を作成しています。Java が私の最初の言語であるため、removeAll 関数を作成して、ヘッド ノードとテール ノードを結合するだけです (センチネル ノードを使用しています)。しかし、ノード用にメモリを解放する必要があるため、これは C++ では機能しないことにすぐに気付きます。
すべての要素を手動で削除して、リスト全体を反復処理する方法はありますか?
したがって、これは少し概念的な質問です。私は C++ で LinkedList を作成しています。Java が私の最初の言語であるため、removeAll 関数を作成して、ヘッド ノードとテール ノードを結合するだけです (センチネル ノードを使用しています)。しかし、ノード用にメモリを解放する必要があるため、これは C++ では機能しないことにすぐに気付きます。
すべての要素を手動で削除して、リスト全体を反復処理する方法はありますか?
各ノードに次のノードを所有させることができます。つまり、それ自体が破棄されたときにそのノードを破棄する責任があります。これは、次のようなスマート ポインターを使用して行うことができます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;
};
これにより、センチネルでの連鎖反応が停止します。
c ++ガベージコレクターを使用すれば、Javaのようにそれを行うことができます。多くはありません。いずれにせよ、リスト内の各要素を割り当てるためのコストを費やすため、実行時間の一定の要素を節約できます。
はい。まあ、一種の...メモリプールを使用するようにリストを実装すると、そのプール内のすべてのデータを担当し、メモリプールを削除することでリスト全体を削除できます(1つ以上の大きなメモリチャンクが含まれる場合があります) )。
メモリ プールを使用する場合、通常、次の考慮事項の少なくとも 1 つがあります。
私はこれについて専門家ではありません。一般に、高速なメモリ管理が必要な場合は、メモリが一度読み込まれ、空きリストなどを維持する必要がありません。特定の目標と設計上の制約がある場合、メモリ プールの設計と実装ははるかに簡単です。すべての状況で機能する魔法の弾丸が必要な場合は、おそらく運が悪い.