Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Properly destroying pointers in an std::map

I have a map declared as

std::map<std::string, Texture*> textureMap; 

which I use for pairing the path to a texture file to the actual texture so I can reference the texture by the path without loading the same texture a bunch of times for individual sprites. What I don't know how to do is properly destroy the textures in the destructor for the ResourceManager class (where the map is).

I thought about using a loop with an iterator like this:

ResourceManager::~ResourceManager() {     for(std::map<std::string, Texture*>::iterator itr = textureMap.begin(); itr != textureMap.end(); itr++)     {         delete (*itr);     } } 

But that doesn't work, it says delete expected a pointer. It's pretty late so I'm probably just missing something obvious, but I wanted to get this working before bed. So am I close or am I totally in the wrong direction with this?

like image 587
Mike Avatar asked Nov 14 '13 05:11

Mike


People also ask

How do I destroy a map in C++?

map::clear() function is an inbuilt function in C++ STL, which is defined in header file. clear() is used to remove all the content from the associated map container. This function removes all the values and makes the size of the container as 0.

Does delete destroy the pointer?

delete keyword in C++Pointer to object is not destroyed, value or memory block pointed by pointer is destroyed. The delete operator has void return type does not return a value.

Are pointers destroyed C++?

Pointers are never destroyed. Objects are destroyed, but pointers aren't objects. A plain old pointer is a primitive data type, like an int or a bool. It doesn't have a constructor or a destructor.

How do I delete a pointer in CPP?

delete and free() in C++ In C++, the delete operator should only be used either for the pointers pointing to the memory allocated using new operator or for a NULL pointer, and free() should only be used either for the pointers pointing to the memory allocated using malloc() or for a NULL pointer.


1 Answers

As far as your sample code goes, you need to do this inside the loop:

delete itr->second; 

The map has two elements and you need to delete the second. In your case, itr->first is a std::string and itr->second is a Texture*.

If you need to delete a particular entry, you could do something like this:

std::map<std::string, Texture*>::iterator itr = textureMap.find("some/path.png"); if (itr != textureMap.end()) {     // found it - delete it     delete itr->second;     textureMap.erase(itr); } 

You have to make sure that the entry exists in the map otherwise you may get an exception when trying to delete the texture pointer.

An alternative might be to use std::shared_ptr instead of a raw pointer, then you could use a simpler syntax for removing an item from the map and let the std::shared_ptr handle the deletion of the underlying object when appropriate. That way, you can use erase() with a key argument, like so:

// map using shared_ptr std::map<std::string, std::shared_ptr<Texture>> textureMap;  // ... delete an entry ... textureMap.erase("some/path.png"); 

That will do two things:

  • Remove the entry from the map, if it exists
  • If there are no other references to the Texture*, the object will be deleted

In order to use std::shared_ptr you'll either need a recent C++11 compiler, or Boost.

like image 147
Roger Rowland Avatar answered Sep 17 '22 21:09

Roger Rowland