Question

In a recent interview, I was asked to answer if this code is safe and if it is when would I use something like this:

template<class T> T *CTricky<T>::Safe_Or_Not (T *object) 
{ 

    object->T::~T (); 

    ::new (object) T; 

    return object; 

 }

My answer was: this code is safe and I would use this technique if I needed to free the resources used by my "object" by calling its destructor, but at the same time I didn't want to deallocate my "object" and wanted it to hold its place in memory (achieved by placement new here).

I honestly am not looking for help to answer this question correctly on the interview. I'm only curious to see if my understanding of placement new and explicit destructor calls are correct.

Was it helpful?

Solution 2

It is NOT safe: Following may produce memory leak: (https://ideone.com/70YqhM)

Base* b = new Derived;
b = Safe_Or_Not(b);

Derived destructor is never called.

And as other mention:

  • No null check.
  • Exception safety is not taken into account

OTHER TIPS

Short answer: while it doesn't necessarily cause problems, doing this really safely is quite difficult. The biggest problem is that if the constructor invoked via the placement new throws, you've already destroyed the object, but then the stack unwinding will try to destroy it again, leading to undefined behavior.

Though there are a few other things to look out for (e.g., null pointer) that's the one that's probably the least obvious and most difficult to keep it from causing problems (basically, about your only choices are to put up with the undefined behavior and hope for the best, or catch the exception and exit from the program before stack unwinding can happen).

I think that the general "explicit destructor call + placement new" logic is safe.
However, this code is not safe, because:
- You do not check if the pointer is null. - Exception safety is not taken into account

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top