In my C++ program, I create objects in one function using new. These objects are inserted into a set. When I want to remove objects from the set, I use an iterator in a for-loop. When I remove the object from the set, I still need to delete the object to free its memory, correct? I tried using delete, but then I get an error saying that the pointer being freed was not allocated. So how can this be done?
Here is the code where I create the object and then insert it into the set
set <myObject> myobjectlist;
myObject *myobject = new myObject;
myobjectlist.insert(*myobject);
In another function, I try to remove an object from the set, and free its memory:
for (set<myObject>::iterator i = myobjectlist.begin(); i != myobjectlist.end(); i++)
if (i->myObjectID == myObjectID)
{
myobjectlist.erase(*i);
delete &i;
break;
}
This works fine without the 'delete' part. I added it in bec开发者_运维问答ause I thought that the memory from the object wasn't being freed.
Assuming you're calling the set's erase()
method, note that this will call the destructor of the object for you. After you erase()
your object, it has already been delete
d, and thus your second attempt to manually call delete will fail as the pointer is no longer allocated.
For reference, see this
Yes, you need to delete objects that you create. However, what is in your set isn't necessarily what you allocated. For example, maybe your set contains object values (rather than pointers) and your allocated object is being leaked after insert. Post code.
Edit: That was it. Your set does not store pointers, it stores copies of the objects you are allocating. Remove the delete from your erase loop and insert the object like this:
set <myObject> myobjectlist;
myobjectlist.insert(myObject());
Alternatively, just make your set be set<myObject*>
.
Also, erase takes an iterator - no need to deref it.
Here is what you want, assuming that you need to use new to allocate these objects:
set <myObject*> myobjectlist;
myObject *myobject = new myObject;
myobjectlist.insert(myobject); //insert the pointer, not the object
for (set<myObject*>::iterator i = myobjectlist.begin(); i != myobjectlist.end(); i++) {
if ((*i)->myObjectID == myObjectID) {
myobjectlist.erase(i);
delete *i;
break;
}
}
If you need a list of pointers, use a list of smart pointers. Use a std algoritm to find the correct item and erase it from the list.
#include <set>
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
using namespace boost;
typedef boost::shared_ptr<MyObject> t_object;
std::set<t_object> myObjectList;
myObjectList.insert(t_object(new MyObject));
std::set<t_object>::iterator item = std::find_if(
myObjectList.begin(),
myObjectList.end(),
bind(&MyObject::myObjectID, _1)== myObjectID);
if(item!=myObjectList.end())
myObjectList.erase(item);
精彩评论