Advertisement

'delete', 'delete []' and safe deletion schemes

Started by October 18, 2000 12:38 AM
19 comments, last by Ratheous 24 years, 2 months ago
Long ago when I first started coding in c++ I found that I often called delete on things that were either uninitialized or had already been deleted, causing crash after crash. I then came up with a bright idea to make a macro to do the checking for me. Since then I've seen various implementations of the same concept. Mine went something like this:
        
#define DeAlloc(OBJ) 
	if(OBJ != NULL)  	delete OBJ;	 	OBJ = NULL
        
Thinking about it now I realize I used this on everything I deleted, but what if I had to delete an array? I'm embarrassed to admit still don't know exactly what the two do beyond that you use 'delete' to free single allocated pointers and 'delete []' to free allocated arrays. Does anyone have more detailed info on this? Do any of you use safe deletion methods such as this one, and if so how does it affect performance? I don't often use the macro any longer, I think it was more a safty net to correct sloppy coding on my part, and I'm trying to avoid that

____________________________________________________
"Two wrongs do not make a right; it usually takes 3 or more."

Edit: clarification Edited by - ratheous on 10/18/00 12:42:54 AM

____________________________________________________
"Two wrongs do not make a right; it usually takes 3 or more."
Some mistakes are too much fun to only make once.
Never anger a dragon, for you are crunchy and you go well with brie.

Firstly, you don''t need to test if the object is NULL if you always set it the pointer to NULL after a delete. delete NULL does nothing.

The difference between delete[] and delete is whether you use new or new[]

    char *p = new char;   // a single object allocation needs deletedelete p;char *q = new char[100];  // array allocation needs delete[]delete q[];    


If you truly want safe deletion methods, you have to look into smart pointers. Then there is no more need for calling delete.
Advertisement
Hi,

just create a second macro that is called SafeDeleteArray() and use this one...

Kind regards,
Metron
----------------------------------------http://www.sidema.be----------------------------------------
quote: Original post by Ratheous
Mine went something like this:
            #define DeAlloc(OBJ) 	if(OBJ != NULL)  	delete OBJ;	 	OBJ = NULL         


I don't often use the macro any longer, I think it was more a safty net to correct sloppy coding on my part, and I'm trying to avoid that



First thing, just to repeat what Void already stated, you don't need to check for NULL, because delete NULL is defined to do nothing.

Second, as Void also stated, use delete to free from new, and delete[] to free from new[].

Now, in addition... You called your macro a safety net; possibly a misnomer, but let's go with that. So why do you want to avoid it? If you write a function that helps you write safer code, GREAT!!! Maybe one day I'll buy a game that isn't already patched before it hits the shelves....

Really, "safety net" functions are good things. Some will argue that you lose performance. This may be true (and it may not; check with a profiler). In any case, coders would be much better off by writing code that FIRST works and SECOND gets optimized. (In all the threads on this forum, I haven't seen a SINGLE good, valid reason why you should optimize code before you get the code correct.) I'm a professional game developer and use such functions all the time. Saves typing, saves redundant code....

So my final point, then, is help in making your safety net functions better. First, if you're using C++, I HIGHLY recommend moving from preprocessor defines to inline and/or templatized functions. For your safe delete, something like:

    template <class T> void DeAlloc(T*& t){  delete t;  t = NULL;}        


While you don't need to check against NULL before calling delete, it may be beneficial to set the pointer to NULL if there is the possibility that the pointer might still be visible to the calling scope.

As for arrays, you could create a safe DeAllocArray() helper to work in a similar fashion, using delete[] instead of delete. Personally, I would go another route; try looking up auto_ptr in your favorite books/websites for something similar to what I use. auto_ptr isn't perfect nor complete, but a great start.


---- --- -- -
Blue programmer needs food badly. Blue programmer is about to die!

Edited by - mossmoss on October 18, 2000 9:40:11 AM
Thanks for the replies

quote:
Firstly, you don't need to test if the object is NULL if you always set it the pointer to NULL after a delete. delete NULL does nothing.

Useful info, thank you.
quote:
just create a second macro that is called SafeDeleteArray() and use this one...

Could do that. The problem would be if I called one in place of the other...
quote:
You called your macro a safety net; possibly a misnomer, but let's go with that. So why do you want to avoid it? If you write a function that helps you write safer code, GREAT!!!

Agreed. While I was perhaps a bit unclear, I don't want to completely do away with 'safety nets' or whatever else they should be called. I suppose that was a gross generalization. Ahwell, it was late I AM however looking for smarter ways of doing it. Taking the unneeded 'if' out improves that. I'm also tracking all allocations/deallocations in debug and printing out a report of anything missed to a log file, among other things planned.
quote:
I haven't seen a SINGLE good, valid reason why you should optimize code before you get the code correct.)

As I mentioned above I'm trying to implement some better coding techniques so that safer, more debuggable code is used in debug output and the optimized versions are substituted in release.
quote:
First, if you're using C++, I HIGHLY recommend moving from preprocessor defines to inline and/or templatized functions. For your safe delete, something like:

template void DeAlloc(T*& t){ delete t; t = NULL;}

Why are inline and/or templatized functions better than preprocessor in this case? I can see that they would be more flexible - atleast templates would be, and I use them in various places, but for something like this? Could you give me a short example of how this would be used and what advantages there are to it?
quote:
Personally, I would go another route; try looking up auto_ptr in your favorite books/websites for something similar to what I use. auto_ptr isn't perfect nor complete, but a great start.

Ok, I'll look into it, thanks


____________________________________________________

"Two wrongs do not make a right; it usually takes 3 or more."



Edited by - ratheous on October 18, 2000 1:01:55 PM

____________________________________________________
"Two wrongs do not make a right; it usually takes 3 or more."
Some mistakes are too much fun to only make once.
Never anger a dragon, for you are crunchy and you go well with brie.

Doesn''t delete (NULL) still incur the function call overhead of the call to delete? Also, I''d never use this macro because most of the time I delete objects from owner objects'' destructors. If it''s a destructor, you don''t need to set the pointer to NULL because it''s about to go away. Saves an instruction.

I found that after I developed good encapsulation techniques, I had about 10% of the pointers that I used to, and only really needed to check vs NULL on about 10% of those.
Advertisement
std::auto_ptr is good, but it''s not for use with array (it uses delete, not delete[]). You should use std::vector or have a look at boost for bigger selection of smart pointers.
Now I have a question too about this whole new/delete thing.
What is exacly the difference between using malloc/free and new/delete?
Someone told me once that I really sould use malloc and free. And that someone is a very good C programmer.
Wat ya think about this?

Dennis



visit my site, please:
members.nbci.com/dennis428/default.htm
visit my site, please:members.nbci.com/dennis428/default.htm
Ratheous: You wanted to know what happens if you use delete on an array? For instance

int * myArray = new int[50];
delete myArray;

Recall that myArray is a pointer to myArray[0]. So you end up releasing the memory allocated to myArray[0]. However, myArray[1], myArray[2], ..., myArray[49] are still allocated, but now you have no pointer to them! This is a memory leak.

denis428: There is a recent thread on "Memory Allocation/De-allocation" that discussed new/delete vs alloc/free a bit. Personally, I stick always with new/delete.
I really did my best looking for the threat, Z01. But I couldn''t find it.
So my question remains.
What is the difference between new/delete and malloc/free?

Dennis


visit my site, please:
members.nbci.com/dennis428/default.htm
visit my site, please:members.nbci.com/dennis428/default.htm

This topic is closed to new replies.

Advertisement