STL 연관 컨테이너(예제: multimap) erase 시 주의 사항!!

Game Programming/C++ 2010. 6. 21. 18:28
STL 연관 컨테이너를 사용하다 보면 아래와 같이 사용하는 경우가 있다.

typedef multimap<int, std::string> _TESTList;

_TESTList lst;
_TESTList::iterator it;
pair< _TESTList::iterator, _TESTList::iterator > range;

for(int i = 0; i < 5; i++)
lst.insert(make_pair(i * 10, "test"));

for(int i = 0; i < 5; i++)
{
lst.insert(make_pair(35, "test35"));
if(i == 3)
lst.insert(make_pair(35, "erase target"));
}

cout << "org : " << endl;
for(it = lst.begin(); it != lst.end(); it++)
cout << it->first << ", " << it->second.c_str() << endl;
cout << "erase 35" << endl;
range = lst.equal_range(35);
for (it = range.first; it != range.second; it++)
{
if( it->second.compare("erase target") == 0 )
lst.erase( it );
}

cout << "after : " << endl;
for(it = lst.begin(); it != lst.end(); it++)
cout << it->first << ", " << it->second.c_str() << endl;

붉은색 하이라이트 부분을 보면 range 를 탐색하며 "erase target"과 동일한
멤버를 찾아 삭제하고 있다. 이대로 실행하면 컴파일러가 에러를 뱉는다.

이유는 it 가 가리키는 요소를 지워 it 가 무효화 되어 it++ 를 수행할 수 없게된다.

아래와 같이 고치면 해결할 수 있다.

<해결 1>
for (it = range.first; it != range.second; )
{
if( it->second.compare("erase target") == 0 )
lst.erase( it++ );
else
it++;
}

<해결 2>
for (it = range.first; it != range.second; )
{
if( it->second.compare("erase target") == 0 )
it = lst.erase( it );
else
it++;
}



설정

트랙백

댓글