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

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

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

/* 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 действителен).

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

Ответы [ 3 ]

24 голосов
/ 13 декабря 2010

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

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

8 голосов
/ 13 декабря 2010

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

this->~Function();

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

0 голосов
/ 13 декабря 2010

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

...