I have a weird problem. I have a map in C defined like this as private in a class.
std::map<const char *, GameObject *> GameObjects;
I have a function that adds pairs to the map.
void myClass::Add(const char *name, GameObject *object)
{
GameObjects.insert(std::make_pair(name, object));
}
It works fine if I add pairs like this.
m_myClass.Add("Example", new GameObject());
Now, the problem is in the Instantiate function, declared like this.
void myClass::Instantiate(GameObject *object)
{
char *name = (char *)malloc(strlen("New Object ") 12); // New Object xxxxxxxxxxxx x -> digit
memset(name, 0, strlen("New Object ") 12); // clear
strcpy(name, "New Object "); // copy the first part
strcpy(name strlen("New Object "), std::to_string(newObjs ).c_str()); // copy the number part
printf("Creating %s", name);
Add(name, object); // add it to our map
}
If I iterate over every item from the map, the pair appears to exist and works indexing it but when I index it manually (GameObjects["pairName"]) the program crashes with a segmentation fault message. Also GameObjects.contains("pairName") returns false even if I added the pair with that name.
I use GCC 11.2.0 on Ubuntu with the C 20 standard enabled.
CodePudding user response:
A string literal has a different pointer value to a return value of malloc. The map will do lookup with std::less<const char *> which compares pointer values, it does not compare text.
Use std::string, and don't use malloc or owning raw pointers.
std::map<std::string, std::unique_ptr<GameObject>> GameObjects;
void myClass::Add(std::string name, std::unique_ptr<GameObject> object)
{
GameObjects.emplace(std::move(name), std::move(object));
}
void myClass::Instantiate(std::unique_ptr<GameObject> object)
{
std::string name{ "New Object " };
name = std::to_string(newObjs )
std::cout << "Creating " << name;
Add(std::move(name), std::move(object));
}
