#pointers #header #array #heap-allocated #size #padding #data

cable

电缆(指针)末尾带有一个钩子(地址处的头),以及一个有固定大小的有效负载(数组)

2个版本

0.1.1 2021年5月8日
0.1.0 2021年5月7日

#567 in 内存管理

MIT/Apache

24KB
382

Cable

Crate

一个带有 hook(地址处的头)的 cable(指针)和有固定大小的 payload(数组)

特性

一种针对堆分配的指针类型,具有一些特殊功能

  • 在地址处存储用户指定的可选头
  • 在行内存储数据的大小
  • 一个可调整大小的数组,带有边界检查,只需要一个指针即可使用
  • 在必要时添加填充,以保持头、大小和元素的对齐

用法

将此添加到您的 Cargo.toml

[dependencies]
cable = "0.1.1"

示例

let mut data: Cable<f64, (i32, i32, i32, i32)> = Cable::with_capacity_zeroed(8, (1, 2, 3, 4));
data[0] = 1.0;
data[1] = 6.0;
data[2] = 9.0;

for i in data.iter() {
    println!("{:?}", i);
}

println!("Header: {:?}", data.header().unwrap());
println!("Footprint: {}", data.footprint());

Cable<T, H> 在创建其他堆对象时很有用。创建具有长度和容量的简单动态存储

let mut data: Cable<i32, usize> = Cable::with_capacity(24, 6); // allocate capacity for 24 elements
data[0] = 19;
data[1] = 22;
data[2] = 35;
data[3] = 53;
data[4] = 68;
data[5] = 13;

println!("Length: {}", data.header().unwrap());
println!("Footprint: {}", data.footprint());

Cable<T, H> 在需要小内存占用时非常适合嵌套结构

let mut x: Vec<Cable<i32>> = Vec::with_capacity(24);
x.push(Cable::with_capacity(2));
x[0][0] = 67;
x[0][1] = 45;

x.push(Cable::with_capacity(8));
x[1][2] = 32;
x[1][5] = 19;

在这种情况下,向量表现得像一个二维数组,但每个元素可以具有可变大小。这允许创建紧凑的数据结构,具有适当的边界检查和最小内存占用。可以使用结构体作为头的方便性

struct Info {
    id: i32,
    position: (f32, f32),
    length: usize,
}

let mut x: Cable<i32, Info> = Cable::with_capacity(
    24,
    Info {
        id: -1,
        position: (0.0, 0.0),
        length: 0,
    },
);

为了简洁,可以省略头

let mut x: Cable<i32> = Cable::new();

安全性

此指针是安全的,因为它总是在堆上分配至少 mem::size_of::<usize>() 字节,并将指向该分配。

分配

电缆有一些特殊的分配功能和注意事项

  • 至少分配 mem::size_of::<H>() + 为 usize 分配的填充 + mem::size_of::<usize>() + T 分配的填充。
  • H 可以是零大小,在这种情况下,例如使用单元类型 H = (),则不分配头。
  • 可选分配零内存。
  • 成本最小,大多数内存布局在编译时确定。
  • 当有效载荷未分配时,类似于 Box<H>(尽管至少有额外的 mem::size_of::<usize>() 字节,见 into_boxed_header)。

包功能

待定,未来可能支持

  • no-std
  • serde
  • 自定义分配器

无运行时依赖