Which version of safe_delete is better?

#define SAFE_DELETE(a) if( (a) != NULL ) delete (a); (a) = NULL; 

OR

 template<typename T> void safe_delete(T*& a) { delete a; a = NULL; } 

or any other better way

+5
source share
9 answers

Clearly, the function is for a simple reason. A macro evaluates its argument several times. This can have evil side effects. Also, the function may be limited. Nothing better than that :)

+5
source

I would say no, because both will give you a false sense of security. For example, suppose you have a function:

 void Func( SomePtr * p ) { // stuff SafeDelete( p ); } 

You set p to NULL, but copies of p outside the function are not affected.

However, if you must do this, go to the template - macros will always have the potential for thromping to other names.

+19
source

delete a;

ISO C ++ indicates that deleting with a NULL pointer just does nothing.

Quote from iso 14882:

  5.3.5 Delete [expr.delete]

     2 [...] In either alternative, if the value of the operand of delete is the 
         null pointer the operation has no effect.  [...]

Regards, Bodo

/ edit: I did not notice a = NULL; in the original post, so the new version: delete a; a = NULL; however, a problem with setting a = NULL has already been indicated (false sense of security).

+7
source

As a rule, prefer built-in functions over macros, because macros do not take into account scope and may conflict with some characters during preprocessing, which leads to very strange compilation errors.

Of course, sometimes templates and functions will not do, but here it is not.

In addition, a safer deletion is not required, since you can use smart pointers, so you do not need to remember this method in client code, but encapsulate it.

( edit ). As others have pointed out, safe removal is unsafe, because even if someone does not forget to use it, it may still not have the desired effect. So this is actually completely useless, because using safe_delete properly requires more thought than just setting it to 0.

+5
source

You do not need to test the nullity value with delete , this is equivalent to no-op. (a) = NULL makes me raise an eyebrow. The second option is better.

However, if you have a choice, you should use smart pointers like std::auto_ptr or tr1::shared_ptr that already do this for you.

+2
source

I think,

#define SAFE_DELETE(pPtr) { delete pPtr; pPtr = NULL } #define SAFE_DELETE(pPtr) { delete pPtr; pPtr = NULL } better

  • its ok to call delete if pPtr is NULL. Therefore, if verification is not required.
  • if you call SAFE_DELETE (ptr + i), this will result in a compilation error.
  • A template definition will create multiple function instances for each data type. In my opinion, in this case, these multiple definitions do not add any value.
  • In addition, when defining a template function, you have the overhead of calling the function.
+2
source

As mentioned above, the second one is the best, and not a macro with potential unintended side effects, does not have an unnecessary check against NULL (although I suspect you are doing this as a type check), etc. But both of them promise no security. If you use something like tr1 :: smart_ptr, make sure you read the documents on them and are sure that you have the right semantics for your task. Recently, I had to track down and clean up a huge memory leak due to the fact that the employee loaded smart_ptrs into the data structure with circular links :) (he had to use weak_ptrs for backlinks)

0
source

Using SAFE_DELETE really represents the approach of C programmers to manage the built-in memory management in C ++. My question is: can C ++ use this method of using SAFE_DELETE for pointers that have been correctly encapsulated as private? Will this macro ONLY work with a pointer declared by Public? OOP dietary supplement !!

0
source

I prefer this version:

 ~scoped_ptr() { delete this->ptr_; //this-> for emphasis, ptr_ is owned by this } 

Setting the pointer to zero after deleting it is completely pointless, since the only reason you will use pointers is to allow the reference to the object in several places at the same time. Even if the pointer in one part of the program is 0, there may be others that are not set to 0.

In addition, the safe_delete macro / function template is very difficult to use correctly, because there are only two places that can be used if there is code that can be thrown between the new one and delete for this pointer.

1) Inside the catch (...) block, which redraws the exception, and is also duplicated next to the catch (...) block for the path that does not throw. (Also duplicated next to each gap, return, continuation, etc., which may allow the pointer to fall out of the area)

2) Inside the destructor for the object to which the pointer belongs (unless there is code between the new and the deleted, which can cause).

Even if there is no code that could be thrown away when you write the code, this may change in the future (all that is required is for someone who comes in and adds another new one after the first). It is better to write code in such a way that it remains true even before exceptions.

Option 1 creates so many duplicates of the code and it is so easy to make a mistake that I doubt that I even called it an option.

Option 2 makes safe_delete redundant, since the ptr_ parameter that you set to 0 will go beyond the scope on the next line.

In conclusion, do not use safe_delete, since it is unsafe (it is very difficult to use correctly and leads to redundant code, even when its use is correct). Use SBRM and smart pointers.

0
source

All Articles