我正在使用Rust调用一个需要空指针作为参数的C函数,然后分配一些内存来指向它。那么,如何高效地(即避免不必要的复制)且安全地(即避免内存泄漏或段错误)将C指针中的数据转换为Vec
?我的代码示例如下:
extern "C" {
// C function that allocates an array of floats
fn allocate_data(data_ptr: *mut *const f32, data_len: *mut i32);
}
fn get_vec() -> Vec<f32> {
// C will set this to length of array it allocates
let mut data_len: i32 = 0;
// C will point this at the array it allocates
let mut data_ptr: *const f32 = std::ptr::null_mut();
unsafe { allocate_data(&mut data_ptr, &mut data_len) };
let data_slice = unsafe { slice::from_raw_parts(data_ptr as *const f32, data_len as usize) };
data_slice.to_vec()
}
如果我理解正确,
.to_vec()
会将数据从切片复制到一个新的 Vec
中,因此底层内存仍需被释放(当切片被丢弃时,底层内存不会被释放)。对于上述情况,应该采取何种正确方法呢?
- 我可以创建一个
Vec
,它拥有底层内存的所有权,在Vec
被释放时,底层内存也会被释放吗? - 如果不能,那么在 Rust 中应该在哪里/如何释放 C 函数分配的内存?
- 上述内容中是否还有其他需要改进的地方?
str::ptr
是一个打字错误,应该是std::ptr
,我会进行修正。关于CVec的优秀想法。有一件事情我仍然不确定 - 我正在封装的API没有为其创建的数组提供释放方法,使用libc::free
是否合适(即在impl Drop
中使用libc::free(self.ptr)
)? - Dave Challislibc::free
是否合适呢?不太确定。这个函数 可能 能用;但在从C语言使用该函数时,您需要调用什么来释放数据?那才是正确的做法。 - Shepmaster