I am passing a raw pointer to two different closures and converting the raw pointer to a reference using Box::from_raw()
and the program is working fine.
However, after converting the raw pointer to reference, the destructor should be called automatically as the documentation says:
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.
However, I am able to access the reference to ABC even after calling Box::from_raw()
on raw pointer twice and it's working fine.
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);
}
Why is the destructor is not called for ABC
after handle
and before handle1
as the description for Box::from_raw()
function specifies:
Specifically, the
Box
destructor will call the destructor ofT
and free the allocated memory.
Why is Box::from_raw()
working multiple times on a raw pointer?
TL;DR you are doing it wrong.
converting the raw pointer to a reference
No, you are converting it into a Box
, not a reference.
the program is working fine
It is not. You are merely being "lucky" that memory unsafety and undefined behavior isn't triggering a crash. This is likely because your type has no actual data.
to reference, the destructor should be called automatically
No, when references go out of scope, the destructor is not executed.
Why is the destructor is not called
It is, which is one of multiple reasons your code is completely and totally broken and unsafe.
Add code to be run during destruction:
impl Drop for ABC {
fn drop(&mut self) {
println!("drop")
}
}
And you will see it is called 3 times:
Inside handle 1
drop
Inside handle 2
drop
drop
I am able to access the reference to ABC
Yes, which is unsafe. You are breaking the rules that you are supposed to be upholding when writing unsafe
code. You've taken a raw pointer, done something to make it invalid, and are then accessing the original, now invalid variable.
The documentation also states:
the only valid pointer to pass to this function is the one taken from another
Box
via theBox::into_raw
function.
You are ignoring this aspect as well.