我注意到*mut [T]有一个len() method.这意味着*mut [T]需要指向包含数组长度和实际数组的某个内存位置的指针,对吗?因此,我不能简单地在这两种类型之间进行转换?或者*mut [T]是胖指针(所以长度不存储在指针后面,而是指针的一部分)?例如,这是合法的吗?

let l = Layout::array::<T>(size).unwrap();
let a = std::alloc::alloc(new_layout) as *mut [T];

或者我应该用*mut T

推荐答案

[T]dynamically sized type (DST).正如您已经怀疑的那样,指向DST的指针是包含长度的胖指针. 您的示例(简化为使用i32而不是T)

fn main() {
    let l = std::alloc::Layout::array::<i32>(10).unwrap();
    let a = std::alloc::alloc(l) as *mut [i32];
}

Demo

将在编译时失败,并显示以下非常有用的错误:

error[E0607]: cannot cast thin pointer `*mut u8` to fat pointer `*mut [i32]`
 --> src/main.rs:5:9
  |
5 | let a = std::alloc::alloc(l) as *mut [i32];
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

For more information about this error, try `rustc --explain E0607`.

这正好证明了这一点.


从细指针创建切片的示例如下所示:

fn main() {
    let layout = std::alloc::Layout::array::<i32>(10).unwrap();
    let slice = unsafe { 
        let ptr = std::alloc::alloc(layout) as *mut i32;
        std::ptr::write_bytes(ptr, 0u8, 10); // initialize memory
        std::slice::from_raw_parts(ptr, 10) 
    };
    println!("{:?}", slice);
}

Demo

Rust相关问答推荐

如何格式化传入Rust中mysql crate的Pool::new的字符串

如何正确地将App handler传递给Tauri中的其他模块?

RUST应用程序正在退出,错误代码为:(退出代码:0xc0000005,STATUS_ACCESS_VIOLATION)

允许 rust 迹 struct 条目具有多种类型

在 Rust 中用问号传播错误时对类型转换的困惑?

当我编译 Rust 代码时,我是否缺少 AVX512 的目标功能?

为什么实现特征的对象期望比具体对象有更长的生命周期?

为什么在 Allocator API 中 allocate() 使用 `[u8]` 而 deallocate 使用 `u8` ?

如何在 Rust 中编写一个通用方法,它可以接受任何可以转换为另一个值的值?

闭包返回类型的生命周期规范

如何为整数切片定义一个带有额外函数的特性别名?

如何基于常量在Rust中跳过一个测试

Rust: 目标成员属于哪个"目标家族"的列表是否存在?

在1.5n次比较中找到整数向量中的最大和次大整数

如何使用泛型满足 tokio 异步任务中的生命周期界限

如何在 Rust 中将 bson::Bson 转换为 Vec

在构建器模式中捕获 &str 时如何使用生命周期?

如何将 Rust 字符串转换为 i8(c_char) 数组?

只有一个字符被读入作为词法分析器的输入

如何将 u8 切片复制到 u32 切片中?