I want to expose a "dynamic array" to a C function. The C function will own the data and later will call a function of mine to free the data. So it'll look something like the following:
fn get_something(len: *mut usize) -> *mut u8;
fn dealloc_something(data: *mut u8, len: usize);
Internally I have a Box<[T]>
(my_vec.to_boxed_slice()
). I can get the size/length pretty easily, but I don't know which pointer I should return. If I pass the pointer returned from boxed_slice.as_mut_ptr()
to Box::from_raw()
, the application crashes. However, if I pass the pointer returned from Box::into_raw
, I can't find a guarantee of memory layout (the pointer points to the first element of the array and will continue to do so for all future Rust versions).
What's the solution here?
Box::into_raw
returns a pointer to the beginning of the allocated storage. A slice is a contiguous sequence of items in memory. Therefore, the pointer points to the first item in the slice. IfBox::into_raw
returned anything else, it wouldn't be really useful.The main difference between
boxed_slice.as_mut_ptr()
andBox::into_raw
is thatBox::into_raw
takes ownership of the box but does not deallocate it, whileboxed_slice.as_mut_ptr()
just returns a copy of the pointer and leaves ownership of theBox
to your function, so the compiler implicitly drops it before returning. This means that when you useboxed_slice.as_mut_ptr()
, you are essentially returning a pointer to freed memory!