티스토리 뷰

/**
  요즘들어 포스팅 하는 주기가 점점 길어 지고 있네요.
  날씨는 점점 추워지고 솔로들이 더욱 살아 남기 힘들어지는 크리스마스
  가 다가 오고 있습니다.

  저도 크리스마스 때 남들처럼 거리를 활보 하고 싶습니다만 겨울의 거리
  는 솔로에겐 냉정하지요.

  올 크리스마스는 징검다리 휴가라, 크리스마스 이브에 휴가를 내면 4일
  을 연속으로 쉴 수 있군요. 하지만 어디 딱히 갈 곳도 없고 오라는 곳도
  없으니, 저는 웹 서핑이나 하면서 블로그 포스팅이나 하렵니다. 
*/

오늘은 stl의 map의 erase에 대해서 간략하게 알아 보겠습니다.
보통 다른 stl의 컨테이너들은 erase를 하는 것에 대해 별다른 신경을 쓰지 않아도 별 문제가 없지만 map이란 녀석은 다른 컨테이너들 처럼 다루면 성질을 부리며 런타임 오류를 내버리는 경우가 있습니다(어쩌면 아무런 오류도 내지 않고 묵묵히 자기 할 일을 할 수도 있습니다만...정상적인 반응은 아닙니다).

위에서 언급 했지만, map 컨테이너의 반복자가 참조하고 있는 원소가 삭제되는 경우 큰 위험성이 있습니다. 예를 들어,

typedef std::map<std::string, float> StringFloatMap;
StringFloatMap coll;
StringFloatMap::iterator pos;
....

for(pos = coll.begin(); pos != coll.end(); pos++) {
    if(pos->second == value) {
        coll.erase(pos);  // 런타임 에러
    }
}

coll.erase(pos) 이후에 coll의 반복자인 pos는 무효화 됩니다. 해당 반복자는 erase에 의해 이미 지워진 요소를 가리키고 있으므로 ++연산자는 정의 되지 않은 결과를 불러 옵니다(위에서 정상적으로 동작 할 수 있다고도 했지요? 정의 되지 않은 결과라서 그런겁니다).

이런 무효화를 방지 하기 위해서는 erase를 호출하기 전에 미리 반복자를 복사하고 erase를 호출 하면 됩니다.

typedef std::map<std::string, float> StringFloatMap;
StringFloatMap coll;
StringFloatMap::iterator pos;
....

for(pos = coll.begin(); pos != coll.end();) {
    if(pos->second == value) {
        coll.erase(pos++);
    }
    else {
        ++pos;
    }
}

coll.erase(pos++)은 다음 원소를 참조하기 위해서 pos를 증가 시킵니다. 하지만 ++ 이라는 것은 내부적으로 복사 하고 증가를 하는 것이기 때문에 pos는 erase에 의해 제거된 원소를 참조 하지 않고, 복사된 것을 참조하게 되므로써 안전하게 증가 할 수 있습니다.

Ref.
 C++ Standard Libarary : Addison Wesley
TAG
,
댓글
  • 프로필사진 Favicon of http://blog.ggamsso.wo.tc BlogIcon 깜쏘 당연한 것을...
    저건 open하지 않은 파일포인터 close하는 것과 같은 격입니다.
    그런데 저는 for보다는 while이 편해서, 저런 식의 실수는 거의 없을 듯^^
    2007.12.13 19:13
  • 프로필사진 Favicon of https://kukuta.tistory.com BlogIcon kukuta 그래? 나는 while보다는 for를 더 선호하는데...

    ㅎㅎ 그리고 물론 알고 있다면 저런 실수를 잘 하지 않겠지..하짐만 아는 사람보다는 모르는 사람이 더 많을 것 같아서 포스팅 했어..

    그래..사실 할게 없어서 그래..ㅠㅠ
    2007.12.13 20:06 신고
  • 프로필사진 Favicon of http://blog.ggamsso.wo.tc BlogIcon 깜쏘 근데 선배...
    어셈코드를 보면 for보다는 while이 빨라요.
    하짐만 => 하지마 입니다.
    2007.12.14 15:20
  • 프로필사진 Favicon of https://kukuta.tistory.com BlogIcon kukuta ㅇㅇ 하짐만 가독성이 더 좋잖아.
    흐음 나만의 생각인가?

    그리고 하짐만은 서울 말이야..후훗..(뜨끔!)
    2007.12.14 20:02 신고
  • 프로필사진 Tiger Hong 잘 봤습니다.
    Windows server 2003 에서만 에러가 생겨서 찾다보니 올려주신 내용이었습니다.
    큰 도움이 되었네요... 감사합니다~ ^^
    2011.01.17 13:50
  • 프로필사진 blueasa 좋은 포스팅 감사합니다. :) 2011.12.08 18:49
  • 프로필사진 dxd 좋은 포스팅 감사합니다. :) 2015.01.16 09:35
댓글쓰기 폼