2

In C++ we use delete operator to delete objects most of the time.

The delete doesn't make pointer value NULL. Is there any way this can be achieved automatically?

e.g.

int *p = new int;
delete p;  // this should deallocate object pointed by p
           // and also initialized value of p = NULL
Unihedron
  • 10,902
  • 13
  • 62
  • 72
Vijay
  • 2,021
  • 4
  • 24
  • 33
  • Why do you think this is a good idea? Search for other questions and/or google for it and you will see that it is not so clear that this won't actually hide bugs in the code (double delete, where the second delete is *ignored* as the pointer was previously set to 0) – David Rodríguez - dribeas Mar 24 '11 at 08:34

10 Answers10

13

There are two issues with your suggestion.

A False Sense of Security

Your proposal induce a false sense of security. Sure, the standard guarantees that if you call delete on a null pointer, it won't blow up. However, you have forgotten one tiny fact: there is not a single pointer to your object.

int* p = new int(8);
int* q = p;
delete p; p = 0;
delete q; // Undefined Behavior

Therefore, this practice is useless. And because a false sense of security is worse than no security at all, I actually strongly discourage it. In the hope that people will think before applying delete nilly-willy.

Which brings us to the second issue

Don't you ever dare using delete

delete should be reserved to implementers of smart pointers or other containers. The following apply:

  • For Expert Only
  • (Experts) Don't*

*There's probably an already existing debugged implementation for what you're trying to achieve.

There are heaps of existing tools to manage memory:

  • the ubiquitous various flavors of smart pointers: std::unique_ptr or std::auto_ptr (depending on your version of C++), std::scoped_ptr, std::shared_ptr (and its comparse std::weak_ptr, or their boost/tr1 equivalent)
  • the ubiquitous various flavors of containers: boost::array, boost::scoped_array, std::vector (and co)
  • and the lesser known, but so useful in OO: boost::ptr_vector (and co)
  • there's even boost::intrusive_ptr and the Boost Intrusive Containers library or the Boost MultiIndex library (with the BiMap derivative)
  • and probably several other boost libraries, perhaps more specialized, like Boost.Signals

With such an heterogeneous wildlife, it's hard to think that you suddenly discovered a new way of using data that is so different from what we do that you would need something else. And if you have, feel free to post it, we'll help you understand how to use those tools to fit your situation (or give you pointers on how to create a new form of smart pointer).

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
5

It doesn't help much anyway, because there could be more than one pointer to the deleted object.

int* p = new int;

int* q = p;

delete p;   // how do we NULL q?

The best idea is to use delete just before p goes out of scope. Or use standard containers so we don't need new/delete at all.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
4

You could write your own wrapper function or macro that would do that. However, it's hard in the general case, because you can pass rvalues to the delete operator. And then what should it assign NULL to?

Sasha Goldshtein
  • 3,499
  • 22
  • 35
  • Sorry but I couldn't understand your statement *you can pass rvalues to the delete operator*, could you elaborate on that? How can you pass an rvalue to `delete`? – liaK Mar 24 '11 at 07:12
  • Actually, the rvalue issue could be solved in C++0x using rvalue references... with an rvalue, you're sure you don't need to nullify. – Matthieu M. Mar 24 '11 at 07:33
4

without any testing whatsoever, I give you this:

template <typename T> void deleteAndNull(const T*& pointer){
    delete pointer;
    pointer = 0;
}
Bwmat
  • 4,314
  • 3
  • 27
  • 42
  • actually I'm not sure about the syntax, but I intended it to be a reference to a pointer. I'm not sure, but I think that will prevent the attempted deletion of something that isn't a pointer – Bwmat Mar 24 '11 at 06:10
  • 2
    @Nawaz: It doesn't matter in this case :) – Yakov Galka Mar 24 '11 at 06:23
  • both are equivalent, with your form, `T` will be deduced to `Foo` and with the simpler `T&`, `T` will be deduced to `Foo*`. The type of `pointer` won't change as long as you don't forget the `&`. One could argue that your form is better in the sense that it could help trim down the overload resolution... but this function is so specialized that it's a marginal benefit (why not take it though!) – Matthieu M. Mar 24 '11 at 07:35
  • 1
    Actually: `T const *&pointer`. Think about `X const *pX = new X(1,2,3); ...; deleteAndNull(pX);`! – Notinlist Jan 28 '14 at 13:47
1

May be a using auto_ptr with pointers will alos save your time.

Yuriy Vikulov
  • 2,469
  • 5
  • 25
  • 32
0

You could write your own function to do it:

void deleteAndReset (void** p)
{
    delete *p;
    *p = null;
}
Andrew Cooper
  • 32,176
  • 5
  • 81
  • 116
0

The easiest way to do this would be to override the operator delete to

  • erase memory
  • Null out the pointer

Read up on operator overloading, is my recommendation. That way, you can preserve all your current code and not have to go through the effort of having to change everything to a function call.

Prime
  • 4,081
  • 9
  • 47
  • 64
0

It is simple to write one like this:

template<class T>
void safe_delete(T*& p)
{
    delete p;
    p = NULL;
}
int main()
{
    int* p = new int;
    safe_delete(p);

    double* p1 = new double;
    safe_delete(p1);

}

Be careful not to use this with arrays though :)

Naveen
  • 74,600
  • 47
  • 176
  • 233
0

Same answer as your other pointer question - use a smart pointer. There's no point reinventing wheels.

Rob Agar
  • 12,337
  • 5
  • 48
  • 63
0

Doing that is incredibly bad practice.

They said it would save your program from crash if there is double-deletion. Alas, making pointer NULL after you deleted object it pointed to, just mask the problem: your program contains bug.

I'm assure you that you want you program to crash as early and as loudly as possible in that case.

Alexander Poluektov
  • 7,844
  • 1
  • 28
  • 32