Деструктор не вызван после уничтожения размещения объекта-new'ed

Я не знал, почему это не работает. Следующее Function создается путем размещения new. Предоставляется функция, которая проверяет, должна ли она быть разрушена, и если это так, вызывает ее деструктор вручную.

Вот тестовый файл, где кажется, что деструктор никогда не вызывается:

/* 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;
};

Я использовал это следующим образом. Сократите приведенный ниже код до минимума, который все еще проявляет проблему. Разумеется, в моей реальной программе память выделяется другим способом, от распределителя.

#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();
}

Вы можете видеть, что я вызываю деструктор в строке, читающей ~Function(). Компилятор принимает, но он не вызывает его: я проверил его, проверив, действительно ли он удаляет код LLVM, который я ему дал (поместите некоторый код в деструктор перед удалением кода LLVM, на который указывает codeptr, в регистр Function действителен).

Я узнал позже о том, что вызывает это. Не могли бы вы предоставить мне объяснение?

Ответы

Ответ 1

Это связано с тем, что ~Function(); не является вызовом деструктора синтаксически здесь. Вместо этого используйте this->~Function();.

~Function(); анализируется как оператор ~ и создание объекта Function в стеке. Function класс имеет operator bool, поэтому он будет скомпилирован.

Ответ 2

Измените явный вызов деструктора на

this->~Function();

В настоящее время ~ Function создает "Function", а затем вызывает побитовый оператор (легально, потому что у вас есть преобразование в bool), а затем уничтожает это, а не вызываемый объект.

Ответ 3

Как я помню, деструктор нельзя назвать явно. Попробуйте переместить код очистки из деструктора в другую функцию и вызовите его.