c++dictionarycstring

C string map key


Is there any issue with using a C string as a map key?

std::map<const char*, int> imap;

The order of the elements in the map doesn't matter, so it's okay if they are ordered using std::less<const char*>.

I'm using Visual Studio and according to MSDN (Microsoft specific):

In some cases, identical string literals can be "pooled" to save space in the executable file. In string-literal pooling, the compiler causes all references to a particular string literal to point to the same location in memory, instead of having each reference point to a separate instance of the string literal.

It says that they are only pooled in some cases, so it seems like accessing the map elements using a string literal would be a bad idea:

//Could these be referring to different map elements?
int i = imap["hello"];
int j = imap["hello"];

Is it possible to overload operator== for const char* so that the actual C string and not the pointer values would be used to determine if the map elements are equal:

bool operator==(const char* a, const char* b)
{
    return strcmp(a, b) == 0 ? true : false;
}

Is it ever a good idea to use a C string as a map key?


Solution

  • Is it possible to overload operator== for const char* so that the actual C string and not the pointer values would be used to determine if the map elements are equal

    No it's not, and yes, it's not a good idea for exactly the reason pointed out in the question and because you don't need char*, you can use a std::string instead. (you can provide a custom compare function - as pointed out by simonc, but I'd advise against it)

    //Could these be referring to different map elements?
    int i = imap["hello"];
    int j = imap["hello"];
    

    Yes, and they can even refer to elements that don't exist yet, but they'll be created by operator[] and be value initialized. The same issue exists with assignment:

    imap["hello"] = 0;
    imap["hello"] = 1;
    

    The map could now have 1 or 2 elements.