要素を削除して反復を無効にする

1762 ワード

反復器は、容器の内部の式を暴露することなく、容器の中のデータにアクセスする方法を提供し、データ容器とアルゴリズムを分離し、反復器という接着剤を利用して彼らを撮合させることを設計しています.
反復器の使用は失効問題に注意しなければならない.(eraseは削除された反復器の次の反復器を返します)
シーケンスコンテナの有効期限:
void test()
{
	vector v = { "aaaaaaaaaa", "bbbbbbbbbb", "ccccccccc", "dddddddd","eeeeeeeeeeeee" };
	vector::iterator it = v.begin();
	for (; it != v.end();)
	{
		if (*it == "ccccccccc")
			v.erase(it);
		else
			it++;
	}
}

例えばvectorの場合、「cccccccc」を削除するとクラッシュする現象が発生するため、vectorはシーケンスコンテナであるため、削除すると「dddddddd」以降の要素はすぐに前に移動します.「cccccccc」はすでに解放された空間ですが、今は未知の空間です.今はその空間に値を割り当てるとエラーが発生します.申請メモリの動作が行われていないためです.現在の方法では、このブロックを使用しないで解放された空間を使用する必要がありますので、コードを修正します.
void test()
{
	vector v = { "aaaaaaaaaa", "bbbbbbbbbb", "ccccccccc", "dddddddd","eeeeeeeeeeeee" };
	vector::iterator it = v.begin();
	for (; it != v.end();)
	{
		if (*it == "ccccccccc")
			it=v.erase(it);
		else
			it++;
	}
}

非順序コンテナの無効化:
void test()
{
	list l;
	l.push_back(1);
	l.push_back(3);
	l.push_back(5);
	l.push_back(7);

	list::iterator it = l.begin();
	for (; it != l.end();)
	{
		if (*it = 4)
		{
			l.erase(it);
		}
		else
			it++;
	}
}

listは双方向チェーンテーブルであるため、現在の反復器を削除すると後ろのノードが見つからないため、ポインタ++が未知の空間を指しているため、プログラムのクラッシュも発生します.修正方式もeraseの戻り反復器を記録し,そのノードを削除する++操作を直接回避し,クラッシュを回避した.
変更後:
void test()
{
	list l;
	l.push_back(1);
	l.push_back(3);
	l.push_back(5);
	l.push_back(7);

	list::iterator it = l.begin();
	for (; it != l.end();)
	{
		if (*it = 4)
		{
			it=l.erase(it);
		}
		else
			it++;
	}
}