I've got some code that allocates some memory using the bindgen-ed C function hal_malloc which returns an *mut *mut c_void. I cast this to *mut *mut f64 to get a double pointer to a mutable f64. f64 can be other types in my real application, but they're always scalars if that makes life any easier. I then want to store a reference to that memory in a struct so I can modify it later.
I'm sort of writing a smart pointer where the allocator is external to the program I guess?
Here's the broken code:
struct Wrapper {
ptr: Box<f64>
}
impl Wrapper {
pub fn new() -> Self {
let ptr = hal_malloc(mem::size_of::<f64>().try_into().unwrap()) as *mut *mut f64;
Wrapper {
ptr: unsafe { Box::from_raw(*ptr) }
};
}
pub fn set_value(&mut self, value: f64) {
// ...
}
pub fn get_value(&self) {
// ...
}
}
What I would like to do for safety's sake is convert *mut *mut f64 to some kind of mutable Box<f64>. I can do this with Box::from_raw(*ptr) as shown above, however that no longer mutates the original hal_malloced memory, which I think is to be expected because I deref ptr in Box::from_raw?
My two questions:
- Does using
Boxmake reading/writing to the original memory any safer inset_valueandget_value? - If so, how do I cast my double-star (
**) pointer into a mutableBoxwhen I create it?