2012-04-05 12 views
4

私のプログラムで辞書を実装するためにC++マップを使用しています。私の関数は引数として構造体を取得し、structure.nameメンバに基づく関連値、つまりchar named[32]を返さなければなりません。次のコードは、私の問題を示していますC++ map :: find char * vs. char []

map <const char *, const char *> myMap; 
myMap.insert(pair<const char *, const char *>("test", "myTest")); 

char *p = "test"; 
char buf[5] = {'\0'}; 
strcpy(buf, "test"); 

cout << myMap.find(p)->second << endl; // WORKS 
cout << myMap.find("test")->second << endl; // WORKS 
cout << myMap.find(buf)->second << endl; // DOES NOT WORK 

第三の場合は動作しませんし、私はそれを動作させるために何をすべき理由を、私はわかりません。 渡された値を見るために上記のコードをデバッグしましたが、私はまだ問題を把握できません。

ありがとうございます!

答えて

8

要素の位置を特定するために、文字列の比較ではなくポインタの比較がmapによって実行されます。最初の2つは、"test"が文字列リテラルであり、同じアドレスを持つためです。 bufは、"test"と同じアドレスを持たないため、最後は機能しません。

修正するには、std::stringを使用するか、char*のコンパレータを定義します。

+2

実際には、同じ文字を持つ2つの文字列リテラルが同じアドレスを持つかどうかは実装定義です。だから '' test "==" test "'は偽であるかもしれません。また、文字列リテラルが重複する可能性があるので、 ''混乱 '+ 3 == "fusion" 'が真実かもしれません。 –

5

マップキーは値ではなくポインタです。コンパイラは賢明なのでポインタは同じだが、bufは別のメモリアドレスであるため、リテラルな「テスト」文字列はすべてストレージを共有する。

char*ではなく、std::stringのような値の同等性セマンティクスを持つマップキーを使用する必要があります。

1

あなたは値ではなくアドレスを比較していると言われました。私はこの記事にリンクしたい:

Is a string literal in c++ created in static memory?

すべてのリテラル文字列リテラルのあなたの比較が基になる型はまだconst char *であっても働いていた(それは、コンパイラにも応じて、なぜこれが説明して同じアドレスを持っていたので、

0

buf [5]によってbufが指すメモリを割り当てているため、 'p'ポインタを使用するとマップで使用されているのと同じメモリ位置を指しているからです。ですから、常にポインタ変数の代わりにkeyにstd :: stringを使用してください。