본문 바로가기
C++/STL

[C++] map 에 값을 입력하지 않아도 찾아지는 경우 - map 사용 시 주의사항

by Warehaus 2021. 7. 18.

C++ 에서 key, value 형식의 데이터를 저장하기 위해서 map 자료구조를 많이 사용하게 되는데, 이 때 조금 주의해야 하는 부분이 있어서 가볍게 정리한다.

우선 내가 하려고 했던 작업은, map 의 find 멤버함수를 이용해서 값이 있는지 여부를 조건문으로 판단하고, 없는 경우 특정 작업을 하려고 했었다.

아래는 코드 예시이다.

void doSomething () 
{
    std::map<char,std::string> mymap;
    
    .... do insertion or nothing
    if ( mymap.find( 'k' ) == mykey.end() )
    {
    	// no data
    }
    else
    {
    	// have one
        func ( mymap[ 'k' ] );
    }        
  return;
}

위 코드의 의도는 mymap에서 k 라는 키가 있으면 func를 돌리고, 없으면 이에 상응하는 동작을 하려 했었다.

그런데 여기서 문제가 생겼는데 나는 어디에서도 insert를 하지 않았는데, 자꾸 find 함수가 k라는 키를 찾아내는 것이다.

여기저기 찾아보고,  코드와 cplusplus.com 에서 동작을 좀 더 확인해 본 결과 아래와 같은 코드에서 발생한 문제임을 알 수 있었다.

void doSomething () 
{
    std::map<char,std::string> mymap;
    
    if ( mymap['k'] )
    	// do something
        
    // do insertion or nothing
    
    if ( mymap.find( 'k' ) == mykey.end() )
    {
    	// no data
    }
    else
    {
    	// have one
        func ( mymap[ 'k' ] );
    }        
    
    return;
}

실제 코드는 멀티스레드 환경이라 위에 예시코드가 조금 이상한 동작이라고 느껴질 수 있지만, 그래도 내가 겪었던 문제를 알려주는데는 부족함이 없는 코드라고 생각이 된다.

mymap['k'] 같이 operator [] 를 사용하는 코드가 find 보다 앞에 사용되고 있어서 map에 key를 삽입하게 되었고 값은 비어있는 상태로 map이 key, value 항목을 갖게되었다. 이에 따라서 find 멤버함수는 'k'키를 찾아버렸고, 아래 함수 'func'는 비어있는 값으로 연산을 수행하게 된 것이다.

operator[] 동작을 한 번이라도 읽어봤다면 이런 실수를 하지않았을 것 같은데, 아무튼 좋은 경험이라 생각한다.

아래는 map::operator[] 의 동작에 대한 설명이다. ( 출처 : cplusplus.com )

Access element

If k matches the key of an element in the container, the function returns a reference to its mapped value.
If k does not match the key of any element in the container, the function inserts a new element with that key and returns a reference to its mapped value. Notice that this always increases the container size by one, even if no mapped value is assigned to the element (the element is constructed using its default constructor).

두번 째 줄에서 매치되는 k가 없는경우 새로운 element를 삽입한다는 것을 알 수 있으며, 이 값이 우리가 정의하지 않은 값일 수 있다는 것을 알아야 map 의 key 비교를 이용한 올바른 조건문 사용이 가능해 질 것이다.