Delete[] Box going over FFI

I'm passing a Boxed sliced over FFI to a C++ method that the destructor delete[] the ptr. Is this safe to do? Thanks!

let mut b = data.into_boxed_slice();
let ptr = b.as_mut_ptr();
let len = b.len();
std::mem::forget(b);
new_data(ptr, len as i32);

pub fn new_data(arg1: *const u8, arg2: ::std::os::raw::c_int)

~Data() {
   delete[] ptr
}
1 Like

No, it is not.

3 Likes

No, when an allocation is made by rust code, it must be deallocated by rust code. It is possible to set a global allocator for rust code, which is not equal to the C allocator. Even if it was, C++ says that only data allocated with new can be deallocated with delete. It is not allowed to mix malloc/free, new/delete, new[]/delete[] and Box::new/std::mem::drop.

4 Likes

The correct method for this is to offer a delete function through your Rust FFI, like this:

/// Allocate something on the Rust heap
pub unsafe extern "C" fn new_data(arg1: *const u8, arg2: ::std::os::raw::c_int) -> *mut u8 {
    let mut v = Vec::new();
    v.extend_from_slice(slice::from_raw_parts(arg1, arg2 as usize));
    let b: Box<[u8]> = v.into_boxed_slice();
    let ptr = b.as_mut_ptr();
    let len = b.len();
    mem::forget(b);
    ptr
}
/// Frees a Rust-allocated array
pub unsafe extern "C" fn delete_data(ptr: *mut u8, len: ::std::os::raw::c_int) {
    mem::drop(Box::from_raw(slice::from_raw_parts(ptr, len as usize)));
}
1 Like

Unfortunately I can't do that. I can't modify the c++ constructor.

Then expose a C function that uses new[] to allocate memory and call it from rust.

1 Like