Seltsames Verhalten bei Benutzung von op[] mit const char * als Schlüssel
-
Hi,
ich habe mein Problem auf folgendes Stück Code reduzieren können:
#include <unordered_map> #include <string> #include <cstdio> using namespace std; static const char * get_key(void) { static char *name = NULL; if (!name) { static char hname[] = "foobar"; name = &hname[0]; } return name; } int main() { unordered_map<const char *, int> map{{"foobar",3}}; fprintf(stderr, "same? %d\n", string("foobar") == get_key()); fprintf(stderr, "val = %d\n", map["foobar"]); fprintf(stderr, "val = %d\n", map[get_key()]); const char * name = get_key(); fprintf(stderr, "val = %d\n", map[name]); return 0; } // Ausgabe: // same? 1 // val = 3 // val = 0 // val = 0Die Ausgabe findet ihr am Ende der Auflistung. val sollte meiner Ansicht nach immer " = 3" in der Ausgabe haben. Aber wenn ich statt einer Zeichenkonstanten wie im ersten Fall einen Zeiger der auf ein statisches Array (siehe Funktion get_key) zeigt habe, dann findet op[] den Schlüssel nicht. Ändere ich get_key wie folgt ab, dann klappt alles:
static const char * get_key(void) { static char *name = "foobar"; return name; }Ich kompiliere den Code wie folgt:
g++ -std=c++0x -o foo foo.ccAber auch mit Änderungen, wie z.B. -O0 ändert sich an dem Verhalten nichts. Ich habe übrigens C++11 verwendet damit der Beispiel-Code kürzer wird (abgesehen von der unordered_map). Das Original initialisiert die map "klassisch".
Die GCC Version ist g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Habt ihr eine Idee woran das liegen kann?
-
Toni R. schrieb:
Habt ihr eine Idee woran das liegen kann?
Eh.. ja. Du solltest der map vielleicht mitteilen, dass sie da strings vergleichen soll, und nicht nur Pointer. Eigentlich offensichtlich, du schlägst dir bestimmt gerade vor die Stirn.

-
Das Problem lässt sich sogar noch weiter reduzieren, nämlich darauf:
#include <iostream> #include <cstring> using namespace std; int main() { const char foo[] = "foobar"; const char bar[] = "foobar"; cout << (foo == bar) << endl; // -> keine Gleichheit cout << (strcmp(foo, bar) == 0) << endl; // Gleichheit }
-
cooky451 schrieb:
Toni R. schrieb:
Habt ihr eine Idee woran das liegen kann?
Eh.. ja. Du solltest der map vielleicht mitteilen, dass sie da strings vergleichen soll, und nicht nur Pointer. Eigentlich offensichtlich, du schlägst dir bestimmt gerade vor die Stirn.

Oh Mann..., eigentlich klar. Kommt vermutlich davon, dass ich gerade in Python ein C++ Code-Generator schreibe. Da ist mein Gehirn wohl gerade im falschen Modus

-
Toni R. schrieb:
Oh Mann..., eigentlich klar. Kommt vermutlich davon, dass ich gerade in Python ein C++ Code-Generator schreibe. Da ist mein Gehirn wohl gerade im falschen Modus

Na ja nicht zwangsläufig, wenn du einfach std::string nehmen würdest..