[STL]당쵀 이해가 되지 않습니다.(제목 정하기가 너무
글쓴이: assa / 작성시간: 목, 2005/08/04 - 7:59오후
소스를 봐주세요..
#include <iostream> #include <map> using namespace std; void add_int(map<char *, int> &tmap, char *a, int i); void main(void) { map<char *, int> tmap; char *a= "a"; for(int i= 0; i < 10; i++){ add_int(tmap, a, i); } map<char *, int>::iterator map_i; map_i= tmap.find(a); if(map_i != tmap.end()) cout << "not end" << endl; else cout << "end" << endl; cout << tmap.size() << endl; } void add_int(map<char *, int> &tmap, char *a, int i) { tmap.insert(pair<char *, int >(a, i)); }
이렇게 하면
결과가 ...
not end
1
이 나옵니다.
그런데
#include <iostream> #include <map> using namespace std; void add_int(map<char *, int> &tmap, char *a, int i); void main(void) { map<char *, int> tmap; char *a= "a"; for(int i= 0; i < 10; i++){ char *c= new char[10]; strcpy(c, a); add_int(tmap, c, i); } map<char *, int>::iterator map_i; map_i= tmap.find(a); if(map_i != tmap.end()) cout << "not end" << endl; else cout << "end" << endl; cout << tmap.size() << endl; } void add_int(map<char *, int> &tmap, char *a, int i) { tmap.insert(pair<char *, int >(a, i)); }
이렇게 하면 결과가
end
10
이렇게 나옵니다.
즉 tmap에 insert는 되었지만, 같은 문자열임에도 불구하고,
다른 문자로 인식되어 insert되는데요..
이는 map의 특징(중복 key 금지)과도 완전히 다른 성격이 있습
니다.
아무리 생각을 해봐도 왜 이렇게 되는지 답을 알수가 없는데요..
map뿐만 아니라 모든 container들은 이렇게 되는 건가요?
STL을 쓸 경우 strcpy는 무조건 쓸 수 없는건가요?
도움을 부탁드립니다.
p.s. 원인을 찾는데만 하루가 걸렸네요 ㅠㅠ..
Forums:
정확한 동작입니다. ^^;
맵에서 키를 비교할 때는 디폴트로 operator<()로 비교합니다.
map<char*, int>라면 char 문자열을 비교하는 게 아니라, char* 주소 값 자체를 비교하는 겁니다.
첫번째 코드에서는 a가 항상 동일하기 때문에 하나만 삽입되었지만, 두번째에서는 루프를 돌때마다 c가 바뀌므로, 10개 모두 인서트됩니다.
STL을 쓸 때는 char* 문자열은 잊어버리고 std::string으로 대체하십시오.
(두번째 코드에서는 new[]로 할당한 메모리를 delete[]로 삭제하는 코드가 있어서 메모리 릭이 발생하는군요. :oops: )
map<string, int>의 경우에는 string::operator<()를 사용하기 때문에 기대한 대로의 동작이 나옵니다.
비교 함수자
cedar님이 말씀하신 것처럼 맵에 원소를 집어넣을 때 포인터 변수를 이용해 키 값을 비교하기 때문이구요.
맵을 선언할 때 비교 함수자를 만들어서 포인터가 아닌 포인터가 가르키는 객체를 비교할 수 있게 하는 것이 가능합니다.
이펙티브 STL의 20번 항목에 이 밥법에 대한 설명이 나와 있습니다.
거짓말이 없다는 것은 현대성보다도 사상보다도
백배나 더 중요한 일이다.
고맙습니다...
고맙습니다.
"STL을 쓸때는 char *를 잊어라.."
이 말이 왠지 가슴에 와닿네요..
댓글 달기