Using Char* as a Key in Std::Map

Using char* as a key in std::map

You need to give a comparison functor to the map otherwise it's comparing the pointer, not the null-terminated string it points to. In general, this is the case anytime you want your map key to be a pointer.

For example:

struct cmp_str
{
bool operator()(char const *a, char const *b) const
{
return std::strcmp(a, b) < 0;
}
};

map<char *, int, cmp_str> BlahBlah;

Using char* as a key in std::map, how does it work

The ordered containers all use equivalence classes: Two values a and b are considered equivalent if neither one is smaller than the other: !(a < b) && !(b < a) or, if you insist on the notation using a binary predicate !pred(a, b) && !pred(b, a).

Note, that you need to keep the pointers live in your map: if the pointers go out of scope you will get strange results. Of course, string literals stay valid throughout the life-time of the program.

using character array as a key in map

Arrays have neither the copy constructor nor the copy assignment operator. And there is no default operator < for arrays.

Instead of array use the standard container std::array.

For example

#include<iostream>
#include <array>
#include<map>

int main()
{
std::map< std::array<char, 10>, int> m;

std::array<char, 10> c = {'1','2','3','4','5','6','7','8','9','0'};
m[c]=78;

return 0;
}

Error trying to find const char* key from std::map

Comparing two const char* for equality does not do what you think it does; it compares pointer values, not the strings that the pointers point to. With string literals this may occasionally "work", but you have no way of knowing that two string literals even with the same characters in it will be stored at the same address. You would have to provide a custom comparator that invokes strcmp, in order to make that work reliably.

You're much better off with a std::map<std::string, std::string>. It doesn't matter that your third-party API gives you const char*: you can simply construct std::strings from those.

This container will have elements with clear ownership and lifetime semantics, and be automatically ordered properly. In short, all your problems will simply go away.

If you still really need to store const char*, be aware that such a requirement is exceedingly rare and should only be even fleetingly considered if you are prepared to litter your code with explanatory comments detailing precisely how and why your container is safe; hint: it almost certainly is not.

Char * as key in a map C++

When you use map<char *, int, cmp_str> m you cannot modify that buffer after you inserted it to std::map as map does not copy data but pointer itself. When you use std::map<std::string,int> std::string does make a copy and that's why it works and it is slower. So you either need to manually create many buffers and store strings in them (and it will make your program slower) or use std::string which is proper and better way.

Right way to use const char* as map key in C++

You can provide your own Comparator class as template parameter for std::map that implements the comparison based on the c-style strings (e.g. using std::strcmp)

If you have fixed string values to compare with, and a fixed number of them, you'll probably be better off calculating hash values for them, and use these as keys in the map. This could speed up searching a lot, though you have to calculate the hash value for a search input.



Related Topics



Leave a reply



Submit