Are there any good reasons (except \"macros are evil\", maybe) NOT to use the following macros ?
#define DELETE( ptr ) \\
i
NULL
after deallocation tends to mask errorsif (ptr != NULL)
checks as a flow control mechanism. Personally, I consider
this a code smell along the lines of void foo(int arg)
being replaced with void
foo(int arg, bool doAdvancedThings=false)
shared_ptr
and
its relatives should always be used for ownership, raw pointers can be used for
other accessif (ptr != NULL)
instead of if (ptr)
... comparing pointers is another code smellBecause DELETE is already defined in winnt.h :
#define DELETE (0x00010000L)
Because it doesn't actually solve many problems.
In practice, most dangling pointer access problems come from the fact that another pointer to the same object exists elsewhere in the program and is later used to access the object that has been deleted.
Zeroing out one of an unknown number of pointer copies might help a bit, but usually this is a pointer that is either about to go out of scope, or set to point to a new object in any case.
From a design point of view, manually calling delete
or delete[]
should be relatively rare. Using objects by value instead of dynamically allocated objects where appropriatem using std::vector
instead of dynamically allocated arrays and wrapping the ownership of objects that have to be dynamically allocated in an appropriate smart pointer (e.g. auto_ptr
, scoped_ptr
or shared_ptr
) to manage their lifetime are all design approaches that make replacing delete
and delete[]
with a "safer" macro a comparatively low benefit approach.
In my judgement, the benefit does not outweigh the cost.
Your macro fails for several reasons:
DELETE (getPtr());
won't compile, because you can't set the function call to null. Or if the pointer is const, your macro will also fail.delete NULL
is allowed by the standard.Finally, as grimner said, you're trying to solve a problem that shouldn't exist in the first place. Why are you manually calling delete at all?` Don't you use the standard library containers? Smart pointers? Stack allocation? RAII?
As Stroustrup has said before, the only way to avoid memory leaks is to avoid having to call delete.