Skip to content

Instantly share code, notes, and snippets.

@abcsharp
Created November 2, 2011 23:39
Show Gist options
  • Save abcsharp/1335313 to your computer and use it in GitHub Desktop.
Save abcsharp/1335313 to your computer and use it in GitHub Desktop.
某C++入門書のstd::mapの使用例として載っている間違ったコード
/*
以下のコードでは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