2012-10-02 3 views
2

다음 코드 세그먼트와 같이 I는, C 스타일 문자열 색인 multimap은을 만들려고 오전 :과 multimap은 항목을 삽입하지

#include <cstring> 
    #include <map> 
    #include <iostream> 

    using namespace std; 

    int main(void) 
    { 
     int i, j; 
     int (*fn_pt)(const char *, const char *) = strcmp; 
     multimap<char *, char *, int (*)(const char *, const char *)>a(fn_pt); 

     for (i = 0; i < 2; i++) 
     { 
      char key[2]; 
      sprintf(key, "%d", i); 
      for (j = 0; j< 5; j++) 
      { 
       char value[2]; 
       sprintf(value, "%d", j); 
       a.insert(pair<char *, char *>(key, value)); 
      } 
     } 

     for (i = 0; i < 2; i++) 
     { 
      char key[2]; 
      sprintf(key, "%d", i); 
      multimap<char *, char *>::iterator it = a.find(key); 
      while (it != a.end()) 
      { 
       cout << it->first << "\t" << it->second <<endl; 
       it++; 
      } 
     } 
    } 

는 단순히의 키를 변경 위의 프로그램을 정수로 변환하면 예상 한 결과가 나옵니다. 그러나 문자열에서 멀티 맵을 인덱싱하면 사용 된 모든 키 값에 대해 모든 값을 표시하지 않고 예기치 않은 (1과 4의 행만 공백으로 구분 된) 예기치 않은 것을 제공합니다.

어디서 잘못 되었나요?

감사

+1

왜'std :: string'을 사용하지 않겠습니까? 표준 C++ 컨테이너에서 'const char *'키와 값을 올바르게 사용하는 것은 어렵다. – kennytm

+0

@KennyTM std :: string을 사용하여 작동하는지 확인합니다. 하지만 나는 C 스타일의 문자열이 너무 작동해야한다고 생각합니다. 특히 비교기에 명시 적으로 지정했기 때문에 더욱 그렇습니다. – Arani

답변

4

strcmpmultimap에서 사용하는 잘못된 술어이다. 술어는 다음을 만족한다 : (a가, b), 완이 비교 클래스의 오브젝트이다

발현 샘플 콘텐츠를 A와 B는 A를 배치 할 경우에 true를 반환한다 키 값인 엄밀한 약한 순서 지정 조작에서는 b보다 빠른 위치.

strcmp 위배 문자열이 동일하지 않은 경우가하는 < B 또는 A> B 중 하나가 0이 아닌 값을 반환 때문.

첫 번째 문자열이 두 번째 문자보다 작은 경우에만 true을 반환하는 고유 한 조건부를 정의해야합니다.

+1

"엄격한 약한 정렬"이라고도합니다. – Xeo

+0

예, 지금 문제를 인식하고 있습니다. – Arani

3
multimap<char *, char *, int (*)(const char *, const char *)>a(fn_pt); 

    for (i = 0; i < 2; i++) 
    { 
     char key[2]; 
     sprintf(key, "%d", i); 
     for (j = 0; j< 5; j++) 
     { 
      char value[2]; 
      sprintf(value, "%d", j); 
      a.insert(pair<char *, char *>(key, value)); 
     } 
    } 

당신은 컨테이너에 두 개의 포인터를 저장하고, 다음은 객체 (keyvalue) 그 포인터가 범위 밖으로 갈 때를 가리을 파괴하고 있습니다. 이로 인해 이제는 의미가없는 정보를 담고있는 컨테이너가 떠납니다.

1

범위를 벗어난 후 keyvalue의 메모리를 사용하고 있습니다. 사실, 모든 char* 포인터는 동일한 스택 메모리 조각을 가리키며, 실제로 그 시점까지 다시 사용할 준비가되었습니다.

strdup()을 사용하여 char * 데이터의 영구 사본을 만들어야합니다. 물론 나중에 할당 해제하는 것에 대해 걱정할 필요가 있습니다.

+0

물론 strcmp도 잘못되었습니다. – Arkadiy

관련 문제