イテレータとdeleteについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
山崎

イテレータとdeleteについて

#1

投稿記事 by 山崎 » 16年前

毎度お世話になっております、山崎です。
イテレータを使ってリストの要素のポインタが指すインスタンスをdeleteしようとしたところ、
出てきたエラーをどうすることもできず皆様のお知恵をお借りしに参りました。
OSはXP,エディタはVisualStudio2008です。

listに格納されたNumberObjectという型のポインタを最初から順番に全て調べ、
NumberObject::DeleteThisがtrueであればそのポインタが指すインスタンスをdeleteし、
listからも削除する、ということを行いたいと思っています。

以下はそのために書いたコードです。
グローバル変数として、他のファイルでlist<NumberObject*> NOM;と宣言してあります。
なお、NumberObject::ObjectMain()はDeleteThisを状況に応じてtrueにする処理です。
listに新しいNumberObjectのポインタを格納する処理は別の場所で行っています。
...
list<NumberObject*>::iterator NOMit=NOM.begin();
while(NOMit!=NOM.end())
{
	(*NOMit)->ObjectMain();
	if((*NOMit)->DeleteThis==true)
	{
		delete *NOMit;
		NOMit=NOM.erase(NOMit);
	}
	else
		++NOMit;
}
...
このコードを実行したところ、
delete *NOMit;
の行でHEAP CORRUPTION DETECTEDというエラーが発生してしまいました。

イテレータ自体をdeleteしてしまったのかな?と思い、
delete *NOMit;
の行を
NumberObject* NOTemp=*NOMit;
delete NOTemp;
としてみましたが、こちらもエラーでした。

どのようにすれば、イテレータが指すポインタが指すインスタンスをdeleteできるのでしょうか。

MNS

Re:イテレータとdeleteについて

#2

投稿記事 by MNS » 16年前

あまり関係ないかもしれないですが、
delete してから 要素をeraseするのは順序的によくないのではないでしょうか?
if((*NOMit)->DeleteThis==true)
{
	NumberObject* p_tmp = *NOMit;
	NOMit=NOM.erase(NOMit);
	delete p_tmp;
}
上のように、いったん要素を取り出して、eraseした後にdeleteしてみてはどうでしょう?

山崎

Re:イテレータとdeleteについて

#3

投稿記事 by 山崎 » 16年前

MNSさん
ご返答誠にありがとうございます。
紹介していただいたコードを実装してみたところ、
メモリリークを起こさず正しく実行しました。
本当にありがとうございます!!

リストから要素を削除する前にdeleteしてはいけないとは知りませんでした。

閉鎖

“C言語何でも質問掲示板” へ戻る