- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Will Crichton 在他 2018 年 2 月题为“Memory Safety in Rust: A Case Study with C”的笔记中写道:
Rust provides the ability to take ownership of raw pointers, which we do using
slice::from_raw_parts_mut
andBox::from_raw
which tells Rust to treat the memory pointer as a heap-allocated array. After transferring ownership, assuming the memory is valid and of the right size/type, Rust applies its usual memory safety and containment checks.
上面提到的他的代码的相关部分是:
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
的文档状态(添加了强调):
Since the way Box allocates and releases memory is unspecified, the only valid pointer to pass to this function is the one taken from another Box via the
Box::into_raw
function.
为避免疑义,(实验)Heap
上面用于执行内存分配的 API(自从在 Rust 1.27.0 中删除)在其 alloc
中直接调用 __rust_alloc
方法——因此 ptr
不是从 Box::into_raw
获得的。
将指向新分配内存的原始指针传递给 Box::from_raw
以使 Rust 取得该内存的所有权并执行其通常的安全和包含检查是否有效(尽管不受支持)?特别是,当出现的 Box 被销毁时,Rust 会释放该内存吗?
如果不是,那么如何强制 Rust 取得这种非安全方法分配的内存所有权?
最佳答案
Is it valid, albeit unsupported, to pass to
Box::from_raw
raw pointers to freshly allocated memory
不,这是无效的。
In particular, will Rust deallocate that memory when the arising
Box
is destroyed?
是的,这就是它无效的原因。
内存分配器提供配对分配和释放例程。当您使用一个分配器分配一 block 内存时,您必须使用该分配器释放它。
如果你不这样做,当执行释放的分配器去执行它需要做的任何簿记时,它不会知道那 block 内存。实际执行分配的分配器永远不会将该内存标记为不可用。
这些担忧也不是虚构的。我有 submitted patches to GLib纠正发生分配/释放不匹配并导致实际问题的地方。
Rust to take such ownership of memory allocated
在原始指针级别,所有权在很大程度上是一种心态,就像在 C 或 C++ 中一样。 拥有这里的东西意味着你有责任适本地清理它。
malloc
和 free
是成对的分配/解除分配方法。您可以创建自己的类型并实现 Drop
为此:
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
会很烦人和 JeMallocBox
和一个 MyCustomAllocBox
,这就是为什么 RFC 1398为分配器提出共享特征。相关work is progressing转换 Box<T>
进入Box<T, A: Alloc + Default = Global>
.
how can one force Rust
没有“强制”Rust 做任何事情的概念,更不用说像这样的低级细节了。例如,无法保证分配指针的 C 代码不会尝试释放指针本身。在 FFI 世界中,所有权是一种合作协议(protocol)。
另见:
关于pointers - 如何强制 Rust 获得非安全方法分配的内存的所有权?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54849928/
我想了解 Ruby 方法 methods() 是如何工作的。 我尝试使用“ruby 方法”在 Google 上搜索,但这不是我需要的。 我也看过 ruby-doc.org,但我没有找到这种方法。
Test 方法 对指定的字符串执行一个正则表达式搜索,并返回一个 Boolean 值指示是否找到匹配的模式。 object.Test(string) 参数 object 必选项。总是一个
Replace 方法 替换在正则表达式查找中找到的文本。 object.Replace(string1, string2) 参数 object 必选项。总是一个 RegExp 对象的名称。
Raise 方法 生成运行时错误 object.Raise(number, source, description, helpfile, helpcontext) 参数 object 应为
Execute 方法 对指定的字符串执行正则表达式搜索。 object.Execute(string) 参数 object 必选项。总是一个 RegExp 对象的名称。 string
Clear 方法 清除 Err 对象的所有属性设置。 object.Clear object 应为 Err 对象的名称。 说明 在错误处理后,使用 Clear 显式地清除 Err 对象。此
CopyFile 方法 将一个或多个文件从某位置复制到另一位置。 object.CopyFile source, destination[, overwrite] 参数 object 必选
Copy 方法 将指定的文件或文件夹从某位置复制到另一位置。 object.Copy destination[, overwrite] 参数 object 必选项。应为 File 或 F
Close 方法 关闭打开的 TextStream 文件。 object.Close object 应为 TextStream 对象的名称。 说明 下面例子举例说明如何使用 Close 方
BuildPath 方法 向现有路径后添加名称。 object.BuildPath(path, name) 参数 object 必选项。应为 FileSystemObject 对象的名称
GetFolder 方法 返回与指定的路径中某文件夹相应的 Folder 对象。 object.GetFolder(folderspec) 参数 object 必选项。应为 FileSy
GetFileName 方法 返回指定路径(不是指定驱动器路径部分)的最后一个文件或文件夹。 object.GetFileName(pathspec) 参数 object 必选项。应为
GetFile 方法 返回与指定路径中某文件相应的 File 对象。 object.GetFile(filespec) 参数 object 必选项。应为 FileSystemObject
GetExtensionName 方法 返回字符串,该字符串包含路径最后一个组成部分的扩展名。 object.GetExtensionName(path) 参数 object 必选项。应
GetDriveName 方法 返回包含指定路径中驱动器名的字符串。 object.GetDriveName(path) 参数 object 必选项。应为 FileSystemObjec
GetDrive 方法 返回与指定的路径中驱动器相对应的 Drive 对象。 object.GetDrive drivespec 参数 object 必选项。应为 FileSystemO
GetBaseName 方法 返回字符串,其中包含文件的基本名 (不带扩展名), 或者提供的路径说明中的文件夹。 object.GetBaseName(path) 参数 object 必
GetAbsolutePathName 方法 从提供的指定路径中返回完整且含义明确的路径。 object.GetAbsolutePathName(pathspec) 参数 object
FolderExists 方法 如果指定的文件夹存在,则返回 True;否则返回 False。 object.FolderExists(folderspec) 参数 object 必选项
FileExists 方法 如果指定的文件存在返回 True;否则返回 False。 object.FileExists(filespec) 参数 object 必选项。应为 FileS
我是一名优秀的程序员,十分优秀!