我正在从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
,它取得底层内存的所有权,当释放_1274205时释放它吗? -
如果不是,在Rust中我应该释放C函数分配的内存?
-
以上可能/应该改进的其他内容?
1 回答
不安全,没有 . 你 must not 使用
Vec::from_raw_parts
除非指针最初来自Vec
(好吧,来自同一个内存分配器) . 否则,您将尝试释放分配器不知道的内存;一个非常糟糕的主意 .一旦你完成它并且不久就完成了 .
调用
slice::from_raw_parts
时无需强制转换指针变量上不需要显式类型
使用
ptr::null
,而不是ptr::null_mut
执行NULL指针检查
检查长度是否定的
您没有说明为什么需要它作为
Vec
,但如果您永远不需要更改大小,您可以创建自己的类型,可以作为切片取消引用并在适当时删除数据:也可以看看:
How to convert a *const pointer into a Vec to correctly drop it?
Is it possible to call a Rust function taking a Vec from C?