STL 컨테이너 요소의 트랩 삭제(회전)

오늘 Scott Meyers 마스터의 stl 사용법을 보고 제가 얼마 전에 범한 오류를 보았습니다. 제가 쓴 코드는 그가 언급한 오류 코드와 거의 똑같습니다. stl 용기에서 요소를 삭제하는 문제와 관련된 오류는 다음과 같습니다.
std::vector<struct> mFriendList;
//...
std::vector<struct>::iterator iter = mFriendList.begin();
for ( ; iter != mFriendList.end(); ++iter)
{
    if (...)
        mFriendList.erase(iter);
}

그때 On ce가 나에게 이 문제를 말하고 코드를 고친 적이 있다는 것을 기억한다. 나는 왜 프로그램이 실행될 때만if가true라면 프로그램이 붕괴될 수밖에 없는지 몰랐다.
대가의 말은 쉬운 원소가 삭제되면 그 원소를 가리키는 모든 교체기가 무효가 된다는 것이다.위 코드에서erase(iter)만 실행하면 iter가 무효가 되고++iter를 실행하면 오류가 발생할 수 있습니다.
인터넷에서 본 사람은 다음과 같은 두 가지를 요약했다.
1. 노드 컨테이너(map,list,set) 요소의 삭제에 대한 삽입 작업은 이 요소를 가리키는 교체기가 효력을 상실하고 다른 요소 교체기는 영향을 받지 않습니다
2. 순서식 용기(vector,string,deque) 요소의 삭제, 삽입 작업은 이 요소와 뒤에 있는 요소를 가리키는 교체기가 효력을 상실할 수 있습니다
요약하고 On ce가 그때 고쳐준 코드를 회상하기 때문에 정확한 작법은 다음과 같아야 한다.
1. 노드 컨테이너의 경우
std::list<struct> mList;
//...
std::list<struct>::iterator iter = mList.begin();
for ( ; iter != mList.end(); )
{
    if (...)
    {
        //                  ,                    ,          
        mList.erase(iter++);
    }
    else
    {
        ++iter;
    }
}

2. 순서식 용기의 경우
std::vector<struct> mVector;
//...
std::vector<struct>::iterator iter = mVector.begin();
for ( ; iter != mVector.end(); )
{
    if (...)
    {
        //         ,                       ,       ++  
        //        erase()                      
        //       erase()     void,         ,      !!!!
        iter = mVector.erase(iter);
    }
    else
    {
        ++iter;
    }
}

텍스트:http://hsw625728.blog.163.com/blog/static/3957072820091189254690/

좋은 웹페이지 즐겨찾기