除了通过其安全方法之外,如何强制 Rust 获取分配的内存的所有权?

2023-11-23

在他 2018 年 2 月题为“Rust 中的内存安全: C 案例研究”,威尔·克莱顿写道:

Rust 提供了获取原始指针所有权的能力,我们使用它slice::from_raw_parts_mut and Box::from_raw它告诉 Rust 将内存指针视为堆分配的数组。转移所有权后,假设内存有效且大小/类型正确,Rust 会应用其通常的内存安全和包含检查。

上面提到的他的代码的相关部分是:

let mut new_data = unsafe {
    let ptr = Heap::default()
        .alloc(Layout::array::<isize>(new_capacity).unwrap())
        .unwrap() as *mut isize;
    Box::from_raw(slice::from_raw_parts_mut(ptr, new_capacity))
};

然而,文档Box::from_raw状态(强调):

由于Box分配和释放内存的方式未指定,传递给该函数的唯一有效指针是通过以下方式从另一个 Box 中取出的Box::into_raw功能。

为避免疑义,(实验)Heap上面用于执行内存分配的 API(自 Rust 1.27.0 中删除)直接调用__rust_alloc in its alloc方法——因此ptr was not从...获取Box::into_raw.

尽管不支持,但传递给是否有效?Box::from_raw指向新分配的内存的原始指针,以便 Rust 获得该内存的所有权并强制执行其通常的安全性和包含检查?特别是,当产生的 Box 被销毁时,Rust 会释放该内存吗?

如果没有,如何can一个人强迫 Rust 取得对通过其安全方法以外的方式分配的内存的所有权?


尽管不支持,但传递给是否有效?Box::from_raw指向新分配的内存的原始指针

不,它无效。

特别是,Rust 会在出现以下情况时释放该内存吗?Box被摧毁了吗?

是的,这就是它无效的原因。

内存分配器提供paired分配和释放例程。当你用一个分配器分配一块内存时,你必须用该分配器释放它.

如果不这样做,当执行释放的分配器去执行它需要执行的任何簿记操作时,它不会知道那块内存。实际进行分配的分配器永远不会将该内存标记为不可用。

这些担忧也不是虚构的。我有向 GLib 提交补丁纠正发生不匹配分配/释放并导致实际问题的地方。

Rust 取得分配的内存的所有权

在原始指针层面,所有权很大程度上是一种心态,就像在 C 或 C++ 中一样。到own这里的某些内容意味着您有责任适当地清理它。

malloc and free是成对的分配/释放方法。您可以创建自己的类型并实现Drop for it:

use libc::{free, malloc};
use std::{ffi::c_void, mem};

struct MallocBox(*mut i32);

impl MallocBox {
    fn new(v: i32) -> Self {
        unsafe {
            let p = malloc(mem::size_of::<i32>()) as *mut i32;
            *p = v;
            Self(p)
        }
    }
}

impl Drop for MallocBox {
    fn drop(&mut self) {
        unsafe { free(self.0 as *mut c_void) }
    }
}

fn main() {
    MallocBox::new(42);
}

真正的实施还将实施Deref可能还有许多其他特征,因此这种类型的使用符合人体工程学。

必须创建一个会很烦人MallocBox and JeMallocBox and a MyCustomAllocBox, 这就是为什么RFC 1398提出了分配器的共享特征。有关的工作正在进行中转换Box<T> into Box<T, A: Alloc + Default = Global>.

怎样才能强制 Rust

不存在“强迫”Rust 做任何事情的概念,更不用说涉及像这样的低级细节了。例如,无法保证分配指针的 C 代码不会尝试释放指针本身。在 FFI 世界中,所有权是一项合作协议。


也可以看看:

  • 如何处理可以拥有或借用的 FFI 未定型类型?
  • 包装拥有或借用数据的 FFI 结构体的更好方法是什么?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

除了通过其安全方法之外,如何强制 Rust 获取分配的内存的所有权? 的相关文章

随机推荐

  • Rails flash[:notice] 总是 nil

    我不明白为什么我的 Rails 视图无法识别 flash notice 或 flash error 关于渲染的部分视图 我不断收到以下错误 具体错误是 ActionView Template Error 当你没有预料到时 你得到了一个 ni
  • 在每个文档中构建具有附加字段的反应式出版物

    我想制作一个包含几个附加字段的出版物 但我不想使用Collection aggregate当集合发生变化时 我的出版物更新就会丢失 所以我不能只使用self added在其中 我打算使用Cursor observeChanges为了实现这一
  • GMP pow 中的溢出处理

    我只是 GMP 库的间接用户 主要通过swi prolog and yap 但我对解决这个问题非常感兴趣 当使用大得离谱的值执行求幂时 主机系统或 GMP 不再能够适当地处理溢出 我已经与上述系统的开发人员交谈过 但他们没有看到解决此问题的
  • 在进程和 DLL 之间共享全局/静态变量

    我只想在进程和进程调用的 dll 之间共享静态 全局变量 exe和dll位于同一内存地址空间 我不希望该变量在其他进程之间共享 问题的阐述 假设有一个静态 全局变量x in a cpp 两个都是exefoo exe和动态链接库bar dll
  • 以编程方式更改 android:digits

    我在布局 xml 中有这个 android digits 0123456789 android inputType phone gt 我想要的是能够以编程方式更改它并且能够来回更改它 输入 Type 部分很好 manual ip setIn
  • 如果特定情况没有返回结果,则使用 count(*) 显示零

    我有一个这样的查询 它返回 city 中每个案例的行数 select case edition id when 6 then DELHI when 50 then AHMEDABAD when 4 then HYDERABAD when 2
  • Android L“令人愉快的”可绘制转换

    Google 是否允许使用图标诸如此类的过渡由开发商创建 或者是开发人员有责任创建这种 令人愉快的 过渡 我真的很想在我的应用程序中实现这些 具体是这样的图标 您可以使用 AnimatedDrawable 和基于位图的框架创建动画图标 在L
  • 缓存 JavaScript 承诺结果

    我会向服务器发出一次调用以获取项目列表 如何确保仅进行一次调用并且仅处理集合一次以创建键值映射 var itemMap function getItems getAllItemsFromServer then function data d
  • 真正的自定义按钮形状

    给定任何形状 实心圆形 星形 三角形 带有透明区域的位图等 我想知道是否可以 使用最新的 Android API 知道用户是否单击了视图或视图之外 例如 如果我有一个圆形按钮 我想知道用户是否在圆圈内单击 而不是在圆圈外单击 是否可以 如果
  • 在android中捏缩放以获得图像视图?

    我有一个要求 我必须在捏合时放大和缩小图像 如果有人可以建议我使用 Imageview 的捏合缩放功能 请 只需执行以下操作即可获得捏缩放 将您的图像放在资产文件夹中并提供此代码 String imageUrl file android a
  • 如何在 Java 中读写时强制使用 UTF-16?

    我发现您可以通过以下方式指定 UTF 16 作为字符集Charset forName UTF 16 并且您可以通过以下方式创建新的 UTF 16 解码器Charset forName UTF 16 newDecoder 但我只看到指定一个的
  • DrawerNavigator:更改文本颜色

    On react navigation s DrawerNavigator 有没有办法改变项目的文本颜色和背景颜色 By default the color scheme looks like the following 由以下内容初始化
  • 如何使用 ORMLite 正确注释继承类?

    我正在尝试将继承与 ORMLite 一起使用 但通过查看文档和谷歌搜索 我无法确定它是否受支持 我想做的是拥有 public abstract class Person public int id public String name pu
  • 如何使用命令提示符导出 mysql 数据库?

    我有一个非常大的数据库 所以我想使用命令提示符导出它 但我不知道如何导出 我正在使用WAMP 首先检查你的命令行是否识别mysql命令 如果没有转到命令并输入 set path c wamp bin mysql mysql5 1 36 bi
  • Win32 应用程序中“WindowProc”的正确返回值

    在 MSDN 的 Win32 Api 文档中 位于http msdn microsoft com en us library ms633573 28VS 85 29 aspx 在WindowProc 它指出 返回值是消息处理的结果 取决于发
  • 使 bash 脚本在 Linux 和 FreeBSD 之间可移植的正确方法是什么?

    我正在编写一些 bash 脚本 我希望这些脚本可以在我的 Linux 和 FreeBSD 系统上运行 因为我主要在 Linux 上工作 所以我习惯用以下命令启动 bash 脚本 bin bash 但这在 FreeBSD 上不起作用 因为 b
  • Microsoft.Owin.Host.SystemWeb 并仍然在上下文中找不到 owin.Environment 项目

    我已经阅读了很多关于此的帖子 但仍然无法使其发挥作用 我正在使用 Visual Studio 2013 我创建了一个新的 MVC 5 项目 并认为使用新的 facebook 登录集成会很酷 它在我的电脑上的 IIS Express 上运行良
  • Facebook 点赞按钮在 Firefox 中显示,但在 IE 中不显示

    我的页面上有一个使用 XBFML 标签的 Facebook Like 按钮 我认为该代码可以正常工作 因为它可以在 Firefox 中正常工作 但在 IE 8 中 在 IE 7 兼容模式下运行 该按钮根本不显示 如果我将其全部切换到 iFr
  • 在 spring(5.0.0.RELEASE) mvc 中加载 swagger-ui.html 时出现错误

    无法解析引用 因为 无法解析指针 definitions Error 在文档中不存在 我点击了这个链接http www baeldung com swagger 2 documentation for spring rest api 但是当
  • 除了通过其安全方法之外,如何强制 Rust 获取分配的内存的所有权?

    在他 2018 年 2 月题为 Rust 中的内存安全 C 案例研究 威尔 克莱顿写道 Rust 提供了获取原始指针所有权的能力 我们使用它slice from raw parts mut and Box from raw它告诉 Rust