如何将 *const 指针转换为 Vec 以正确删除它? [英] How to convert a *const pointer into a Vec to correctly drop it?

查看:32
本文介绍了如何将 *const 指针转换为 Vec 以正确删除它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

询问之后我应该如何释放内存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...

首先,警告:

  1. 不要不要使用Vec::from_raw_parts,除非指针最初来自Vec.不能保证任意指针与Vec兼容,如果继续操作,很可能会在程序中产生巨大的漏洞.

  1. Do not use Vec::from_raw_parts unless the pointer came from a Vec originally. There is no guarantee that an arbitrary pointer will be compatible with a Vec 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.这仅在 lencapacity 相等时才可接受.

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 以正确删除它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆