4

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?

vinipsmaker
  • 2,215
  • 2
  • 19
  • 33

1 Answers1

2

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!

Francis Gagné
  • 60,274
  • 7
  • 180
  • 155
  • _This means that when you use `boxed_slice.as_mut_ptr()`, you are essentially returning a pointer to freed memory_... actually I was using `mem::forget`, but this isn't important. – vinipsmaker Sep 05 '16 at 13:38
  • Can you link me to a reference of such memory layout? `Box::into_raw` will return a pointer to the first element? If this is true, my question is answered and I don't need to ask anything else. – vinipsmaker Sep 05 '16 at 13:39
  • 1
    "Slices are a view into a block of memory represented as a pointer and a length." [doc](https://doc.rust-lang.org/std/slice/). Memory layout of slice data is unspecified. You need to call `as_mut_ptr` on the slice to get valid pointer to data. – Pavel Strakhov Sep 05 '16 at 14:16
  • @vinipsmaker: You might want to [file an issue](https://github.com/rust-lang/rust/issues) (if there isn't one already) to ask for the documentation to be clarified. – Francis Gagné Sep 05 '16 at 15:37