C++ template function to delete and reset pointers

2.8k views Asked by At

I just ran into a minor problem regarding pointers. As I wanted to have a quick and easy way to do this task in a single line:

...
delete pointer;
pointer = 0;
...

I just quickly set up a simple header file with a template method that accepts any type of pointer. It looks like this:

#ifndef P_DELETE_H
#define P_DELETE_H

template <typename T>
void pDelete(T* pointer) {
  if (pointer) {
    delete pointer;
    pointer = 0;
  }
}

#endif

However, the results don't meet my expectations of the object beeing deleted and the pointer beeing reset. Instead, it seems that only the object was deleted, but setting it to zero had no effect (which is what I'd need). If somebody here could lighten me up a little and explain this behavior, I'd apreceate that much!

UPDATE:

As the answers explain, using std::unique_ptr and std::shared_ptr is the safer way to go than nullifying this pointers.

But if you really need to go such way as I requested, the following code will do the trick:

template <typename T>
inline void pDelete(T*& pointer) {
  if (pointer) {
    delete pointer;
    pointer = 0;
  }
}

However, this is generally unsafe to use, even though it correctly deletes and nullifies the pointer on all instances (quick test revealed this).

Thanks to everyone for the informative answers!

3

There are 3 answers

7
Barry On

The solution you're looking for is:

delete pointer;
pointer = nullptr;

Yeah, just write that code in-line. There's really no reason to introduce another function template somewhere that people will have to look up to figure out what it actually does, just to save one line of code.

The above is perfectly readable and easy to understand.

4
SergeyA On

The whole thing you are trying to do is moot. Have you thought about the reason why this is not happening automatically? Why runtime doesn't nullify the pointer after deletion? Because C++ standard committee wasn't smart enough?

No. Because it does you no good most of the time. Yes, you nullify this instance of the pointer - but the whole reason why you had the pointer to begin with is likely that this pointer is living somewhere else well! (there are exceptions to this, of course). As a result, all your nullifying is saving you from is incorrect access on this instance of the pointer - but not on any other instance. In essence, it gives you false feeling of safety.

Rather than engaging in false feeling of safety, adopt usage of automatic pointers - std::unique_ptr should be first choice, and if it doesn't suffice, std::shared_ptr - but make sure you really need it!

2
Caleth On

Stop using raw pointers to denote ownership. If you take ownership of an object through a pointer, it should go into a std::unique_ptr.

Your situation is then pointer.reset().

If you want to let other code observe the object owned by you, without a transfer of ownership, you can use pointer.get() to get a non-owning pointer. You can also use *pointer to get a reference.

If you have to pass that ownership through an interface that uses raw pointers (I'm looking at you, Qt), use pointer.release().