为什么不为 Box::from_raw() 调用析构函数?

Why is the destructor not called for Box::from_raw()?

我将原始指针传递给两个不同的闭包,并使用 Box::from_raw() 将原始指针转换为引用,程序运行良好。

然而,在将原始指针转换为引用后,应该会自动调用析构函数,如文档所述:

This function is unsafe because improper use may lead to memory problems. For example, a double-free may occur if the function is called twice on the same raw pointer.

但是,即使在对原始指针调用 Box::from_raw() 两次后,我仍然能够访问对 ABC 的引用,并且它工作正常。

struct ABC {}

impl ABC {
    pub fn new() -> ABC {
        ABC {}
    }

    pub fn print(&self, x: u32) {
        println!("Inside handle {}", x);
    }
}

fn main() {
    let obj = ABC::new();
    let const_obj: *const ABC = &obj;

    let handle = |x| {
        let abc = unsafe { Box::from_raw(const_obj as *mut ABC) };
        abc.print(x);
    };
    handle(1);

    let handle1 = |x| {
        let abc = unsafe { Box::from_raw(const_obj as *mut ABC) };
        abc.print(x);
    };
    handle1(2);
}

Rust Playground

为什么 ABChandle 之后和 handle1 之前不调用析构函数,因为 description for Box::from_raw() 函数指定:

Specifically, the Box destructor will call the destructor of T and free the allocated memory.

为什么 Box::from_raw() 在原始指针上工作多次?

TL;DR 你做错了。


converting the raw pointer to a reference

不,您正在将其转换为 Box,而不是引用。

the program is working fine

不是。您只是 "lucky" 内存不安全和未定义行为不会触发崩溃。这可能是因为您的类型没有实际数据。

to reference, the destructor should be called automatically

不,当references超出范围时,析构函数不会被执行。

Why is the destructor is not called

,这是您的代码完全损坏且不安全的多种原因之一。

销毁时添加代码运行:

impl Drop for ABC {
    fn drop(&mut self) {
        println!("drop")
    }
}

你会看到它被调用了 3 次:

Inside handle 1
drop
Inside handle 2
drop
drop

I am able to access the reference to ABC

是的,这是不安全的。您违反了编写 unsafe 代码时应该遵守的规则。您使用了一个原始指针,做了一些使其无效的操作,然后访问了现在无效的原始变量。

文档指出:

the only valid pointer to pass to this function is the one taken from another Box via the Box::into_raw function.

你也忽略了这方面。