Created
November 2, 2011 23:39
某C++入門書のstd::mapの使用例として載っている間違ったコード
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
以下のコードではmapのキーとしてchar*が使われているが、 | |
ポインタ型の比較は持っているアドレスが等しいかどうかで判断するので、意図した動作はしない。 | |
この場合正しくはstd::stringを使うべき。 | |
しかし、この入門書ではVisual C++で開発している前提なので、動きが異なってくる。 | |
理由は「文字列プール」という等価な文字列リテラルは全て同一の実体として | |
(要するにコード中に"A"というリテラルが複数あった場合、それらのアドレス全て同じになる) | |
扱うように最適化する機能が有効になっている為に、当初意図していた通りに動作してしまう。 | |
※文字列プールは/GF(無効化は/GF-)オプションで、明示的に有効無効を指定しないと/O1,/O2,/ZIの | |
どれかが指定されているとき自動的に有効にされる。 | |
*/ | |
#include <iostream> | |
#include <map> | |
int main(void) | |
{ | |
char* str="あ";//1 | |
std::map<const char*,int> Map; | |
Map.insert(std::pair<const char*,int>("あ",1));//2 | |
Map.insert(std::pair<const char*,int>("い",2)); | |
Map.insert(std::pair<const char*,int>("う",3)); | |
std::cout<<"あ:"<<Map["あ"]<<std::endl;//3 | |
std::cout<<"あ:"<<Map[str]<<std::endl; | |
//1,2,3はすべて文字列プールにより同じ物として扱われるので画面には1が2つ表示される。(正しい動作は0が2つ表示される) | |
/* | |
ちなみに、map::operator[]は存在しないキーを渡しても勝手に新しい値を作って返そうとするので危険。 | |
atまたはfindを使うべし。 | |
*/ | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment