我提供了两个管理内存的函数:
unsafe extern "system" fn alloc<A: Alloc>(
size: usize,
alignment: usize,
) -> *mut c_void { ... }
unsafe extern "system" fn free<A: Alloc>(
memory: *mut c_void
) { ... }
这两个函数在内部都使用 allocator-api .
这些签名无法更改。问题是 free
不要求 size
和 alignment
,这是 Alloc::dealloc
所必需的.为了解决这个问题,alloc
为一个 Layout
分配一些额外空间. free
现在可以访问这个 Layout
获取所需的额外数据。
最近,allocator-api改变了而不是*mut u8
它现在使用 NonNull<Opaque>
.这是我的问题发生的地方。
An opaque, unsized type. Used for pointers to allocated memory. [...] Such pointers are similar to C’s
void*
type.
Opaque
不是 Sized
, 所以使用 NonNull::as_ptr().add()
和 NonNull::as_ptr().sub()
被禁止。
以前,我使用过类似的东西(为简单起见,我假设 Alloc
的函数是静态的):
#![feature(allocator_api)]
#![no_std]
extern crate libc;
use core::alloc::{Alloc, Layout};
use libc::c_void;
unsafe extern "system" fn alloc<A: Alloc>(
size: usize,
alignment: usize,
) -> *mut c_void
{
let requested_layout =
Layout::from_size_align(size, alignment).unwrap();
let (layout, padding) = Layout::new::<Layout>()
.extend_packed(requested_layout)
.unwrap();
let ptr = A::alloc(layout).unwrap();
(ptr as *mut Layout).write(layout);
ptr.add(padding)
}
NonNull<Opaque>
不再可能最后一行.我该如何解决这个问题?
最佳答案
我可能会这样写,使用 NonNull::as_ptr
得到 *mut Opaque
然后将其转换为不同的具体类型:
#![feature(allocator_api)]
#![no_std]
extern crate libc;
use core::alloc::{Alloc, Layout};
use libc::c_void;
unsafe fn alloc<A: Alloc>(allocator: &mut A, size: usize, alignment: usize) -> *mut c_void {
let requested_layout = Layout::from_size_align(size, alignment).expect("Invalid layout");
let (layout, _padding) = Layout::new::<Layout>()
.extend_packed(requested_layout)
.expect("Unable to create layout");
let ptr = allocator.alloc(layout).expect("Unable to allocate");
// Get a pointer to our layout storage
let raw = ptr.as_ptr() as *mut Layout;
// Save it
raw.write(layout);
// Skip over it
raw.offset(1) as *mut _
}
unsafe extern "system" fn alloc<A: Alloc>(
这对我来说毫无意义。各种 FFI ABI(“C”、“系统”等)无法指定 Rust 泛型类型。将此功能标记为 extern
似乎非常不正确.
Layout::new::<Layout>().extend_packed(requested_layout)
这看起来很可能被破坏了。作为documentation for Layout::extend_packed
状态,强调我的:
the alignment of
next
is irrelevant, and is not incorporated at all into the resulting layout.
您返回的指针似乎不符合对齐请求。
关于rust - 如何向/从 NonNull<Opaque> 添加/减去偏移量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50373726/