Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Destructor not called after destroying object placement-new'ed

I had no clue why this doesn't work. The following Function is created by placement new. A function is provided that checks whether it should be destructed, and if so, calls its destructor manually.

Here is the testcase where it seems the destructor is never called:

/* Represents a function at runtime */ 
class Function {
public:
  /* Creates an invalid function */
  Function():codeptr(0) { }

  /* Creates a function with the given code pointer */
  Function(void *codeptr):codeptr(codeptr) { }

  /* Frees the function machine code */
  ~Function() {
    if(*this) {
      /* <- I explicitly put a debug output here! */
      destroyLLVMCode(codeptr);
    }
  }

public:
  /* Returns true if the function is valid 
   * (if the code pointer is non-null)
   */
  operator bool() const { return codeptr != 0; }

  /* Destroy this function by calling its destructor */
  void destroy() { ~Function(); }

private:
  void *codeptr;
};

I used this like the following. Cut down the code below to the minimum that still exhibits the problem. In my real program, of course, the memory is allocated in another manner, from an allocator.

#include <new>
#include <cstdlib>

int main() { 
  void *buffer = std::malloc(sizeof(Function));
  Function *f = new (buffer) Function(someExecutableLLVMCode);
  /* more code .. register with symbol tables etc.. */
  f->destroy();
}

You can see I'm calling the destructor in the line reading ~Function(). The compiler accepts, but it doesn't end up calling it: I verified it by checking whether it really deletes the LLVM code I gave it (put some code into the destructor before deleting the LLVM code that the codeptr points to, in case the Function is valid).

I found out later on what is causing that. Could you please provide me with an explanation?

like image 947
Johannes Schaub - litb Avatar asked Dec 13 '10 05:12

Johannes Schaub - litb


People also ask

Does placement new call destructor?

¶ Δ Probably not. Unless you used placement new , you should simply delete the object rather than explicitly calling the destructor.

What happens when destructor is not called?

It is automatically called when an object is destroyed, either because its scope of existence has finished (for example, if it was defined as a local object within a function and the function ends) or because it is an object dynamically assigned and it is released using the operator delete.

When an object is destroyed destructor is automatically called?

A destructor is a member of a function which is automatically called when the class is destroyed. It has the same name as the class name but is preceded by a tilde (~). Normally a destructor is used to clean-up when the class is destroyed. C++ Program 12.1 has a class which is named class_ex.

Does the destructor automatically get called?

A destructor is a member function that is invoked automatically when the object goes out of scope or is explicitly destroyed by a call to delete .


2 Answers

This is because ~Function(); in not a destructor call syntactically here. Use this->~Function(); instead.

~Function(); is parsed as an operator ~ and creation of the Function object on the stack. Function class has an operator bool that's why this will be compiled.

like image 196
Kirill V. Lyadvinsky Avatar answered Sep 24 '22 15:09

Kirill V. Lyadvinsky


Change your explicit destructor call to

this->~Function();

Currently the ~Function is constructing a "Function" and then calling the ~ bitwise operator, (legal because you have a conversion to bool), and then destructing that, not the called object.

like image 25
Keith Avatar answered Sep 25 '22 15:09

Keith