Reputation: 148
Basically I have a class that contains a map of structs that I have also defined. In the class, I have a member function to create a new struct and add it to the map (which takes a const char*
as the key). For some reason, my map only seems to be storing the most recent key added, but it does store the value correctly.
Here is a snippet of my relevant code:
#include <map>
struct PlotData{
int item_count;
PlotData(){
item_count = 0;
}
};
Class PlotConfig{
public:
std::map <const char*, PlotData> plots;
void add_set(const char* key){
plots[key] = PlotData();
// added prints to see what's going on
printf("Printing all plot names... Key is %s\n", key);
for (std::map<const char*, PlotData>::iterator it=plots.begin(); it!=plots.end(); ++it){
printf("Key: %s, Items at key: %d\n", it->first, it->second.item_count);
}
printf("Done\n)
}
void delete_set(const char* key){
plots.erase(key);
}
}
It may be of relevance that I'm actually wrapping this in cython and calling it from python using a custom imgui library that is also wrapped in cython, but basically, from my python, I can call like this:
conf = PlotConfig()
conf.add_set("First")
conf.add_set("Second")
conf.add_set("Third")
and I get the output
Printing all plot names... Key is First
Key: First, Items at key: 0
Done
Printing all plot names.. Key is Second
Key: , Items at key: 0
Key: Second, Items at key: 0
Done
Printing all plot names.. Key is Third
Key: , Items at key: 0
Key: , Items at key: 0
Key: Third, Items at key: 0
Done
If people are curious, there is an intermediary cython class that actually wraps PlotConfig and its functions, and when I pass a key from Python, in the cython, I use key.encode('UTF-8')
to encode it into a byte string for use in C++. Aanyways, it appears that my keys are only storing temporarily. When I call delete_set()
with a key, it does not properly delete because it isn't seeing the keys.
Any ideas what's going on?
Upvotes: 0
Views: 341
Reputation: 12263
If you want to use char *
you need to give a comparison functor to the map. Otherwise, it's comparing the pointer, not the null-terminated string it points to.
Something like this:
struct cmp {
bool operator()(char const *a, char const *b) const {
return std::strcmp(a, b) < 0;
}
};
std::map<const char *, PlotData, cmp> myMap;
One additional issue (as pointed out in one of the comments) when using char *
as a key is that storing pointers only does a shallow copy, and the output shows that the data pointed to goes out of scope.
If you want your keys to be null-terminated string, I suggest using std::string
instead.
Upvotes: 6