Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass a boxed slice (`Box<[T]>`) to a C function?

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?

like image 861
vinipsmaker Avatar asked Sep 01 '25 10:09

vinipsmaker


1 Answers

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. If Box::into_raw returned anything else, it wouldn't be really useful.

The main difference between boxed_slice.as_mut_ptr() and Box::into_raw is that Box::into_raw takes ownership of the box but does not deallocate it, while boxed_slice.as_mut_ptr() just returns a copy of the pointer and leaves ownership of the Box to your function, so the compiler implicitly drops it before returning. This means that when you use boxed_slice.as_mut_ptr(), you are essentially returning a pointer to freed memory!

like image 118
Francis Gagné Avatar answered Sep 04 '25 08:09

Francis Gagné