问题描述
在询问之后我应该如何释放内存FFI 边界,Rust reddit 上有人建议我可以使用 Vec::from_raw_parts
从以下结构构造向量,而不是将我的结构包装在 Box
中,并且这可以安全地删除:
After asking how I should go about freeing memory across the FFI boundary, someone on the Rust reddit suggested that rather than wrapping my structs in a Box
, I could use Vec::from_raw_parts
to construct a vector from the following struct, and that this could be safely dropped:
#[repr(C)]
pub struct Array {
data: *const c_void,
len: libc::size_t,
}
然而,from_raw_parts
似乎需要 *mut _
数据,所以我不知道如何继续......
However, from_raw_parts
seems to require *mut _
data, so I'm not sure how to proceed…
推荐答案
非常简短的答案是 self.data as *mut u8
.但是,让我们谈谈更多细节...
The very short answer is self.data as *mut u8
. But, let's talk more details...
首先,警告:
不要不要使用
Vec::from_raw_parts
,除非指针最初来自Vec
.不能保证任意指针与Vec
兼容,如果继续操作,很可能会在程序中产生巨大的漏洞.
Do not use
Vec::from_raw_parts
unless the pointer came from aVec
originally. There is no guarantee that an arbitrary pointer will be compatible with aVec
and you are likely to create giant holes in your program if you proceed.
不要不要释放不属于您的指针.这样做会导致双重释放,这会在您的程序中造成其他大漏洞.
Do not free a pointer that you don't own. Doing so leads to double frees, which will blow other large holes in your program.
您需要知道向量的容量,然后才能重建它.您的示例结构仅包含 len
.这仅在 len
和 capacity
相等时才可接受.
You need to know the capacity of the vector before you can reconstruct it. Your example struct only contains a len
. This is only acceptable if the len
and capacity
are equal.
现在,让我们看看我是否可以遵循自己的规则......
Now, let's see if I can follow my own rules...
extern crate libc;
use std::mem;
#[repr(C)]
pub struct Array {
data: *const libc::c_void,
len: libc::size_t,
}
// Note that both of these methods should probably be implementations
// of the `From` trait to allow them to participate in more places.
impl Array {
fn from_vec(mut v: Vec<u8>) -> Array {
v.shrink_to_fit(); // ensure capacity == size
let a = Array {
data: v.as_ptr() as *const libc::c_void,
len: v.len(),
};
mem::forget(v);
a
}
fn into_vec(self) -> Vec<u8> {
unsafe { Vec::from_raw_parts(self.data as *mut u8, self.len, self.len) }
}
}
fn main() {
let v = vec![1, 2, 3];
let a = Array::from_vec(v);
let v = a.into_vec();
println!("{:?}", v);
}
请注意,我们不必对 Vec
进行任何显式删除,因为 Vec
的正常 Drop
实现开始发挥作用.我们只需要确保我们正确构造了一个 Vec
.
Note that we don't have to do any explicit dropping of the Vec
because the normal Drop
implementation of Vec
comes into play. We just have to make sure that we construct a Vec
properly.
这篇关于如何将 *const 指针转换为 Vec 以正确删除它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!