ページ 11

イテレータとdeleteについて

Posted: 2009年5月16日(土) 11:07
by 山崎
毎度お世話になっております、山崎です。
イテレータを使ってリストの要素のポインタが指すインスタンスを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できるのでしょうか。

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

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

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

Posted: 2009年5月16日(土) 16:17
by 山崎
MNSさん
ご返答誠にありがとうございます。
紹介していただいたコードを実装してみたところ、
メモリリークを起こさず正しく実行しました。
本当にありがとうございます!!

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