ベクトル消去イテレータ: 落とし穴について
ベクトルを扱う場合、予期しない動作を避けるために消去イテレータを正しく使用することが重要です。この記事では、ループによる要素の消去に関連する一般的な落とし穴について説明します。
次のコードを考えてみましょう。
int main() { vector<int> res; res.push_back(1); vector<int>::iterator it = res.begin(); for ( ; it != res.end(); it++) { it = res.erase(it); //if (it == res.end()) // return 0; } }
ドキュメントによると、消去イテレータは「を指しています」関数呼び出しによって消去された最後の要素に続く要素の新しい位置。」これは、シーケンス内の最後の要素を消去すると、反復子がベクトルの終わりを指すことになることを意味します。
しかし、 == res.end() かどうかをチェックせずにこのコードを実行すると、プログラムはクラッシュします。これはなぜですか?
インクリメント トラップ
この動作を理解する鍵は、for ループの動作方法にあります。ループの各反復の後、反復子は自動的にインクリメントされます。これは、最後の要素が消去された場合、反復子はベクトルの末尾を指すことになりますが、これはインクリメントする有効な位置ではありません。
if (it == res.end()) を追加することで、 0を返します。チェックしてください。最後の要素が消去され、反復子が最後を指している場合を処理します。これにより、インクリメント操作によるクラッシュが防止されます。
より効率的なアプローチ
上記のアプローチは機能しますが、ベクトルからすべての要素を消去するより効率的な方法があります。 。ベクターを反復処理して各要素を個別に消去する代わりに、単に res.clear() を呼び出すだけで、ループを必要とせずにベクター全体が消去されます。
条件付き消去
ただし、条件に基づいて特定の要素のみを削除する必要がある場合は、次を使用できます。 pattern:
for ( ; it != res.end(); ) { if (condition) { it = res.erase(it); } else { ++it; } }
このアプローチにより、ベクトルを反復処理し、各要素の条件を確認し、条件が満たされた場合にのみ要素を削除できます。
以上がループ内のベクター要素を消去するとクラッシュが発生するのはなぜですか?また、それを回避するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。