Posted on 2008/12/01 02:01
Filed Under ProgrammingTip

STL Map은 시퀀스 컨테이너(Sequence container)처럼 [ ] 연산자를 제공합니다. 중요한 점은 "C++ Standard Library 튜토리얼·레퍼런스(인포북, 니콜라이 M. 조슈티스)" 책에도 나와 있듯이 [ ] 연산자의 인덱스는 정수 값이 아니라 map의 key 이라는 것입니다. 이것을 정확하게 숙지하지 않고 잘못사용하면, 심각한 문제가 생길 수 있습니다. 아래는 [ ] 연산자를 잘못 사용한 코드의 예입니다.
// 커피 자판기를 하나 만들고, 판매할 커피를 추가합니다.
std::map<int, std::string> mapCoffeeMachine;

mapCoffeeMachine[0] = "Espresso";
mapCoffeeMachine[1] = "Macchiato";
mapCoffeeMachine[2] = "ConPana";
mapCoffeeMachine[3] = "Latte";
mapCoffeeMachine[4] = "Cappuccino";
mapCoffeeMachine[5] = "Mcha";
mapCoffeeMachine[6] = "Caramel";
mapCoffeeMachine[7] = "Americano";

// 생각을 해보니 라떼와 카푸치노는 제고가 없네요.
// 라떼와 카푸치노 버튼을 자판기에서 사용하지 않습니다.
mapCoffeeMachine.erase( 3 );
mapCoffeeMachine.erase( 4 );

...

// 한 구매자가 자판기 앞에서 돈을 넣고 아메리카노를 누릅니다.
for ( int i = 0; i < mapCoffeeMachine.size(); i++ )
{
    if ( mapCoffeeMachine[i] == "Americano" )
    {
        ... // 따끈따끈한 아메리카노 한잔이 나옵니다.!?
    }
}

과연 구매자는 자판기에서 따뜻한 아메리카노 한잔을 뽑아 담배와 함께 커피한잔을 할 수 있을까요? 평생을 기다려도 아메리카노는 나오지 않습니다. 위의 코드는 [ ] 연산자의 인덱스를 정수 값으로 취급한 상당히 잘못된 코드입니다. 문제점은 크게 두 가지로 나뉠 수 있는데, 첫 번째는 size() 함수로 컨테이너의 크기를 구하면 제거된 3, 4번 키 값 때문에 사이즈가 6 이 됩니다. 그러므로 6, 7번 key 값은 아예 비교 대상이 안 됩니다. 커피를 마시러 온 사람은 메뉴를 보고 눌렀는데, 커피는 않나오고 동전이 반환된 꼴이 된 것입니다. 그러나 커피가 않나오는 것보다 더 큰 문제점이 있습니다. 바로 제거한 3, 4번 키 값의 내용이 == 동등 연산자를 통해 빈 value 값이 다시 추가가 된다는 점입니다. 컨테이너의 크기는 8이 되어 이제 커피메뉴에는 8개로 등장하는데, 아무것도 없는 메뉴가 자판기에서 눌러질 수 있다는 사실입니다. 커피가 들어있지 않는 빈 컵만 받게 되겠지요.

위에는 단순히 자판기로만 예를 들었지만 삭제한 내용이 다시 추가되는 문제점은 실제 개발 시에 큰 문제점을 가져올 수 있습니다. 특히 여러 명의 개발자가 작업을 할 경우 개발자 마다 서로 다른 작업방식으로 프로그램이 다운될 수도 있습니다. 이러한 문제점 때문에 컨테이너를 순회할 때는 반드시 반복자를 사용하는 게 필요합니다.



포이트리 로고
직원 할인으로 점심식사 후 거의 매일가는 서초동 포이트리 커피숍 :)
크리에이티브 커먼즈 라이센스
Creative Commons License
2008/12/01 02:01 2008/12/01 02:01

트랙백 주소 : http://nekothink.com/trackback/28

About

by 외계고양이

Counter

· Total
: 82627
· Today
: 22
· Yesterday
: 53