pub struct Layout { /* private fields */ }
Expand description
一块内存的布局。
Layout
的实例描述了特定的内存布局。
您将 Layout
作为输入分配给分配器。
所有布局都具有关联的大小和 2 的幂次对齐。
(请注意,布局不要求具有非零大小,即使 GlobalAlloc
要求所有内存请求的大小为非零。
调用者必须确保满足这样的条件,使用要求较宽松的特定分配器,或者使用更宽松的 Allocator
接口。)
Implementations§
source§impl Layout
impl Layout
const: 1.50.0 · sourcepub const fn from_size_align(
size: usize,
align: usize
) -> Result<Self, LayoutError>
pub const fn from_size_align( size: usize, align: usize ) -> Result<Self, LayoutError>
从给定的 size
和 align
创建 Layout
,或者如果不满足以下任何条件,则返回 LayoutError
:
-
align
不能为零, -
align
必须是 2 的幂, -
size
向上取整到align
的最接近倍数时,不得溢出 isize (即取整后的值必须小于或等于isize::MAX
)。
const: 1.36.0 · sourcepub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self
pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self
const: unstable · sourcepub fn for_value<T: ?Sized>(t: &T) -> Self
pub fn for_value<T: ?Sized>(t: &T) -> Self
产生描述记录的布局,该记录可用于为 T
分配支持结构 (可以是 trait 或其他未定义大小的类型,例如切片)。
const: unstable · sourcepub unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self
🔬This is a nightly-only experimental API. (layout_for_ptr
#69835)
pub unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self
layout_for_ptr
#69835)产生描述记录的布局,该记录可用于为 T
分配支持结构 (可以是 trait 或其他未定义大小的类型,例如切片)。
Safety
仅在满足以下条件时,此函数才可以安全调用:
- 如果
T
是Sized
,则调用该函数始终是安全的。 - 如果
T
的未定义大小的尾部为:-
slice,则切片尾部的长度必须是初始化的整数,并且 entire 值(动态尾部长度 + 静态大小的前缀) 的大小必须适合
isize
。 -
一个 trait 对象,那么指针的 vtable 部分必须指向一个由 unsizing coercion 获得的类型
T
的有效 vtable,并且整个值 (动态尾部长度 + 静态大小前缀) 的大小必须适合isize
。 -
一个不稳定的 外部类型,则此函数始终可以安全调用,但可能会 panic 或以其他方式返回错误的值,因为外部类型的布局未知。 这与在外部类型尾巴上引用
Layout::for_value
时的行为相同。 -
否则,保守地不允许调用此函数。
-
const: unstable · sourcepub fn dangling(&self) -> NonNull<u8>
🔬This is a nightly-only experimental API. (alloc_layout_extra
#55724)
pub fn dangling(&self) -> NonNull<u8>
alloc_layout_extra
#55724)创建一个悬垂的 NonNull
,但此 Layout 非常适合该 NonNull
。
请注意,该指针值可能表示一个有效的指针,这意味着不得将其用作 “尚未初始化” 的标记值。 延迟分配的类型必须通过其他某种方式来跟踪初始化。
1.44.0 · sourcepub fn align_to(&self, align: usize) -> Result<Self, LayoutError>
pub fn align_to(&self, align: usize) -> Result<Self, LayoutError>
创建一个描述记录的布局,该记录可以保留与 self
相同的布局值,但也与对齐方式 align
对齐 (以字节为单位)。
如果 self
已经满足规定的对齐方式,则返回 self
。
请注意,无论返回的布局是否具有不同的对齐方式,此方法都不会在整体大小上添加任何填充。
换句话说,如果 K
的大小为 16,则 K.align_to(32)
仍 的大小为 16。
如果 self.size()
和给定的 align
的组合违反 Layout::from_size_align
中列出的条件,则返回错误。
const: unstable · sourcepub fn padding_needed_for(&self, align: usize) -> usize
🔬This is a nightly-only experimental API. (alloc_layout_extra
#55724)
pub fn padding_needed_for(&self, align: usize) -> usize
alloc_layout_extra
#55724)返回必须在 self
之后插入的填充量,以确保以下地址满足 align
(以字节为单位)。
例如,如果 self.size()
为 9,则 self.padding_needed_for(4)
返回 3,因为这是获得 4 对齐地址所需的最小填充字节数 (假设相应的存储块从 4 对齐地址开始)。
如果 align
不是 2 的幂,则此函数的返回值没有意义。
注意,返回值的实用程序要求 align
小于或等于整个分配的内存块的起始地址的对齐方式。满足此约束的一种方法是确保 align <= self.align()
。
1.44.0 (const: unstable) · sourcepub fn pad_to_align(&self) -> Layout
pub fn pad_to_align(&self) -> Layout
通过将布局的大小四舍五入到布局的对齐方式的倍数来创建布局。
这等效于将 padding_needed_for
的结果添加到布局的当前大小。
sourcepub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError>
🔬This is a nightly-only experimental API. (alloc_layout_extra
#55724)
pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError>
alloc_layout_extra
#55724)创建一个布局,以描述 self
的 n
实例的记录,并在每个实例之间使用适当的填充量,以确保为每个实例提供其请求的大小和对齐方式。
成功后,返回 (k, offs)
,其中 k
是数组的布局,offs
是数组中每个元素的起点之间的距离。
算术溢出时,返回 LayoutError
。
1.44.0 · sourcepub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError>
pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError>
创建一个布局,描述 self
的记录,后跟 next
的记录,包括确保 next
正确对齐但必须填充 no trailing 的所有必要填充。
为了匹配 C 表示形式的布局 repr(C)
,应在扩展了所有字段的布局后调用 pad_to_align
。
(由于未指定,因此无法匹配默认的 Rust 表示形式布局 repr(Rust)
。)
请注意,最终布局的对齐方式将是 self
和 next
的最大对齐方式,以确保两个部分的对齐方式。
返回 Ok((k, offset))
,其中 k
是串联记录的布局,offset
是嵌入在串联记录中的 next
起始位置的相对位置 (以字节为单位) (假定记录本身从偏移量 0 开始)。
算术溢出时,返回 LayoutError
。
Examples
要计算 #[repr(C)]
结构体的布局以及字段与其字段布局的偏移量,请执行以下操作:
pub fn repr_c(fields: &[Layout]) -> Result<(Layout, Vec<usize>), LayoutError> {
let mut offsets = Vec::new();
let mut layout = Layout::from_size_align(0, 1)?;
for &field in fields {
let (new_layout, offset) = layout.extend(field)?;
layout = new_layout;
offsets.push(offset);
}
// 记得用 `pad_to_align` 来完成!
Ok((layout.pad_to_align(), offsets))
}
Runsourcepub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError>
🔬This is a nightly-only experimental API. (alloc_layout_extra
#55724)
pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError>
alloc_layout_extra
#55724)创建一个布局,该布局描述 self
的 n
实例的记录,每个实例之间没有填充。
请注意,与 repeat
不同,即使给定的 self
实例正确对齐,repeat_packed
也不能保证 self
的重复实例将正确对齐。
换句话说,如果使用 repeat_packed
返回的布局来分配数组,则不能保证数组中的所有元素都将正确对齐。
算术溢出时,返回 LayoutError
。
sourcepub fn extend_packed(&self, next: Self) -> Result<Self, LayoutError>
🔬This is a nightly-only experimental API. (alloc_layout_extra
#55724)
pub fn extend_packed(&self, next: Self) -> Result<Self, LayoutError>
alloc_layout_extra
#55724)创建一个布局,描述 self
和 next
的记录,两者之间没有其他填充。
由于没有插入填充,因此 next
的对齐方式是无关紧要的,并且不会将 at all 合并到结果布局中。
算术溢出时,返回 LayoutError
。