Rust 中数组的原始指针和切片指针

问题描述 投票:0回答:1

我试图更好地理解 Rust 的原始指针,我认为下面的代码会失败(很抱歉可能出现 UB)[Playground]:

fn main() {
    println!("size of * const u32 ->{}", std::mem::size_of::<* const u32>());
    println!("size of * const [u32;13] ->{}", std::mem::size_of::<* const [u32;13]>());
    println!("size of * const [u32] ->{}", std::mem::size_of::<* const [u32]>());
    let x = 1u32;
    let arr = [1,2,3,4,5,6,7,8, 9, 10, 11, 12, 13u32];
    let px: * const u32 = &x;
    let parr: * const [u32;13] = &arr;
    let slice: &[u32] = &arr;
    let pslice: * const [u32] = slice;
    unsafe { println!("px -> {:?}", px.as_ref()) };
    unsafe { println!("parr -> {:?}", parr.as_ref()) };
    unsafe { println!("pslice -> {:?}", pslice.as_ref()) };
    //
    println!("How could this work:");
    let pslice2: * const [u32] = parr; // How could this work ?
    unsafe { println!("pslice2 -> {:?}", pslice2.as_ref()) }; // How could this work ?
}

但它甚至与 miri 一起工作:

Standard Error

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 1.16s
     Running `/playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/cargo-miri runner target/miri/x86_64-unknown-linux-gnu/debug/playground`

Standard Output

size of * const u32 ->8
size of * const [u32;13] ->8
size of * const [u32] ->16
px -> Some(1)
parr -> Some([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])
pslice -> Some([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])
How could this work:
pslice2 -> Some([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])

我对切片指针的大小为 16 而数组指针的大小为 8 并不感到惊讶,因为类型不包括数据的大小。但是为什么

let pslice2: * const [u32] = parr;
之后的代码
let parr: * const [u32;13] = &arr;
会被接受以及为什么
pslice.as_ref()
会产生一些数据?

arrays pointers rust slice
1个回答
0
投票

我想从

pslice2
(一个简单的指针(仅地址))初始化
parr
(一个胖指针(地址+大小))可能看起来很奇怪,因为 parr 中缺少的
size
信息对于
 是必需的pslice2

但是这个信息是编译器知道的;这就是为什么

parr
能够访问数组中的所有元素。
然后在
pslice2
初始化期间,编译器会简单地提供“缺失”size 信息。
完成后,
pslice2
是全胖指针(地址+大小),然后可以访问数组中的所有元素。

© www.soinside.com 2019 - 2024. All rights reserved.