5

I'm using C++ map to implemented a dictionary in my program. My function gets a structure as an argument and should return the associated value based on structure.name member which is char named[32]. The following code demonstrates my problem:

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

I am not sure why the third case doesn't work and what should I do to make it work. I debugged the above code to watch the values passed and I still cannot figure the problem.

Thanks!

Neysor
  • 3,893
  • 11
  • 34
  • 66
Mark.A
  • 53
  • 5

4 Answers4

9

Pointer comparison, not string comparison, will be performed by map to locate elements. The first two work because "test" is a string literal and will have the same address. The last does not work because buf will not have the same address as "test".

To fix, either use a std::string or define a comparator for char*.

hmjd
  • 120,187
  • 20
  • 207
  • 252
  • 2
    Actually, it's implementation-defined whether two string literals with the same characters have the same address. So `"test" == "test"` may be false. Also, string literals may overlap, so `"confusion" + 3 == "fusion"` may be true. – Derek Ledbetter Apr 05 '12 at 20:52
5

The map key is a pointer, not a value. All your literal "test" strings share storage, because the compiler is clever that way, so their pointers are the same, but buf is a different memory address.

You need to use a map key that has value equality semantics, such as std::string, instead of char*.

Russell Borogove
  • 18,516
  • 4
  • 43
  • 50
1

Like was mentioned you are comparing on the address not the value. I wanted to link this article:

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

Since all the literals had the same address this explains why your comparison of string literals worked even though the underlying type is still a const char * (but depending on the compiler it may not ALWAYS be so)

Community
  • 1
  • 1
devshorts
  • 8,572
  • 4
  • 50
  • 73
0

Its because by buf[5] you are allocating the memory pointed by buf but when u use 'p' pointer it points to the same memory location as used by map. So always use std::string in key instead of pointer variable.