2010-12-13 45 views
13

Tôi không biết tại sao điều này không hoạt động. Function sau được tạo bởi vị trí mới. Một hàm được cung cấp để kiểm tra xem nó có bị hủy hay không và nếu có, hãy gọi hàm hủy của nó theo cách thủ công.Thiết bị hủy không được gọi sau khi phá hủy đối tượng được sắp xếp mới

Đây là testcase nơi có vẻ như destructor không bao giờ được gọi là:

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

Tôi sử dụng này như sau. Cắt giảm mã dưới đây xuống mức tối thiểu vẫn còn hiện ra vấn đề. Trong chương trình thực sự của tôi, tất nhiên, bộ nhớ được phân bổ theo cách khác, từ một cấp phát.

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

Bạn có thể thấy tôi đang gọi hàm hủy trong dòng đọc ~Function(). Trình biên dịch chấp nhận, nhưng nó không kết thúc bằng cách gọi nó: tôi đã xác minh nó bằng cách kiểm tra xem nó có thực sự xóa mã LLVM mà tôi đã cung cấp hay không (đặt một số mã vào trình phá hủy trước khi xóa mã LLVM mà codeptr trỏ tới, trong trường hợp Function hợp lệ).

Tôi đã tìm hiểu sau về những gì đang gây ra điều đó. Bạn có thể vui lòng cung cấp cho tôi một lời giải thích?

+0

Mã này không bao giờ tạo một hàm theo bất kỳ cách nào và không bao giờ gọi bất kỳ phương thức nào, vì vậy nó không ngạc nhiên khi nó cũng không bao giờ phá hủy bất kỳ đối tượng hàm nào ... –

+0

@Johannes, làm thế nào để bạn tạo cá thể ở đây? Vị trí đó 'mới' ở đâu? –

+0

@Johannes: nghỉ ngơi, ngủ trưa, bất cứ điều gì. ;-) ví dụ mã của bạn không minh họa sự cố. bạn đang nói bạn đã tìm ra nguyên nhân nhưng bạn đang yêu cầu giải thích. điều này chỉ là lộn xộn. bạn có thể xóa câu hỏi và đăng bài vào ngày mai không? –

Trả lời

24

Điều này là do ~Function(); không phải là cú pháp hủy cuộc gọi ở đây. Sử dụng this->~Function(); để thay thế.

~Function(); được phân tích cú pháp làm toán tử ~ và tạo đối tượng Function trên ngăn xếp. Function lớp học có một số operator bool đó là lý do tại sao điều này sẽ được biên soạn.

+6

Nhưng nếu không, nếu bạn phải viết 'Function :: ~ Function()', thì, thì hàm '~ Function()' được phân tích là gì? Áp dụng tiêu cực bitwise cho đối tượng 'Hàm' tạm thời? Điều đó không nên biên dịch, tôi nghĩ vậy. OH UPDATE: anh ta có một chuyển đổi ẩn thành 'bool'. J H H H N N N S, đừng làm thế! –

+0

'Chức năng :: ~ Hàm()' cũng không hoạt động. Tiêu chuẩn nói bạn nên viết 'ptr-> ~ Function()'. –

+0

Vâng, Chức năng :: ~ Chức năng() sẽ hoạt động tốt. Nhưng bạn đúng về '~ Function()'. Nó được mô tả trong 5.3.1/9 trong tiêu chuẩn thánh C++. –

-1

Khi tôi nhớ lại hàm hủy không thể được gọi một cách rõ ràng. Hãy thử di chuyển mã dọn dẹp từ destructor sang chức năng khác và gọi nó thay thế.

+0

Bạn có thể gọi destructors một cách rõ ràng (đó là khó khăn hơn để thảo luận về các cuộc gọi constructor rõ ràng vì không có cú pháp cho các cuộc gọi constructor ở tất cả, nó ở cấp độ ngữ nghĩa, nhưng destructor cuộc gọi thậm chí không có vấn đề về thuật ngữ đó: tất cả đều rất rõ ràng). –

+0

chúng ta có thể gọi một destructor hoàn toàn chỉ như dưới đây: Obj o; o. ~ Obj(); Không giống như cách thực hiện trong phương thức "mayBeDestroy". Nó phải có lỗi biên dịch. Khác nó phải được gọi là Hàm :: ~ Hàm(); – Arunmu

+0

Cảm ơn, tôi thấy bây giờ. – ruslik

8

Thay đổi cuộc gọi destructor cho phép của bạn để

this->~Function(); 

Hiện nay ~ Chức năng được xây dựng một "chức năng" và sau đó gọi ~ điều hành Bitwise, (hợp pháp bởi vì bạn có một sự chuyển đổi đến bool), và sau đó huỷ rằng , không phải là đối tượng được gọi.

Các vấn đề liên quan