I have got some code which uses a lot of pointers pointing to the same address. Given a equivalent simple example:
int *p = new int(1);
int *q = p;
int *r =
The answer, without resorting to managed pointers, is that you should know whether or not to delete a pointer based on where it was allocated.
Your example is kind of contrived, but in a real world application, the object responsible for allocating memory would be responsible for destroying it. Methods and functions which receive already initialized pointers and store them for a time do not delete those pointers; that responsibility lies with whatever object originally allocated the memory.
Just remember that your calls to new
should be balanced by your calls to delete
. Every time you allocate memory, you know you have to write balancing code (often a destructor) to deallocate that memory.
I would say that some times, smart pointers can actually slow down your application, albiet not by a lot. What I would do is create a method, like so:
void safeDelete(void **ptr)
{
if(*ptr != NULL)
{
delete ptr;
*ptr = NULL;
}
}
I'm not sure if I did it 100% correctly, but what you do is you pass the pointer into this method that takes the pointer of a pointer, checks to make sure the pointer it points to isn't set to NULL, then deletes the object and then sets the address to 0, or NULL. Correct me if this isn't a good way of doing this, I'm also new to this and someone told me this was a great way of checking without getting complicated.
Your tool is shared_ptr
of the boost
library. Take a look at the documentation: http://www.boost.org/doc/libs/1_44_0/libs/smart_ptr/shared_ptr.htm
Example:
void func() {
boost::shared_ptr<int> p(new int(10));
boost::shared_ptr<int> q(p);
boost::shared_ptr<int> r(q);
// will be destructed correctly when they go out of scope.
}
The "modern" answer is to use a smart pointer and don't do any manual deletes.
boost::shared_ptr<int> p(new int(1));
boost::shared_ptr<int> q = p;
boost::shared_ptr<int> r = q;
End of story!
There are some very rare cases where you might not be able to use a smart pointer (probably dealing with old code), but cannot use a simple "ownership" scheme either.
Imagine you have an std::vector<whatever*>
and some of the whatever*
pointers point to the same object. Safe cleanup involves ensuring you don't delete the same whatever twice - so build an std::set<whatever*>
as you go, and only delete the pointers that aren't already in the set. Once all the pointed-to objects have been deleted, both containers can safely be deleted as well.
The return value from insert
can be used to determine whether the inserted item was new or not. I haven't tested the following (or used std::set for a while) but I think the following is right...
if (myset.insert (pointervalue).second)
{
// Value was successfully inserted as a new item
delete pointervalue;
}
You shouldn't design projects so that this is necessary, of course, but it's not too hard to deal with the situation if you can't avoid it.
Why are you trying to delete pointers arbitrarily? Every dynamically allocated object is allocated in one place, by one owner. And it should be that one owners responsibility to ensure the object is deleted again.
In some cases, you may want to transfer ownership to another object or component, in which case the responsibility for deleting also changes.
And sometimes, you just want to forget about ownership and use shared ownership: everyone who uses the object shares ownersip, and as long as at least one user exists, the object should not be deleted.
Then you use shared_ptr
.
In short, use RAII. Don't try to manually delete objects.