【问题标题】:Rust: load values from raw pointersRust:从原始指针加载值
【发布时间】:2021-09-07 14:45:10
【问题描述】:

我实际上是想了解如何使用带有 rust 的指针来存储和加载数据,但是当我运行这段代码时:

#[cfg(test)]
mod tests{
    fn get_pointer<T>(a:T) -> *const i32{
        ptr::addr_of!(a)
    }

    #[test]
    fn f(){
        unsafe {
            let a = 5;
            let pointer = get_pointer(a);
            let encoded = bincode::serialize(&(pointer as usize)).unwrap();
            let decoded = bincode::deserialize::<usize>(&encoded[..]).unwrap() as *const i32;
            let b = std::ptr::read(decoded);
            assert_eq!(a, b);
        }
    }
}

存储在b 中的值变为0 而不是5,我无法弄清楚为什么会发生这种情况以及如何解决这个问题。

我认为问题的出现是因为在函数返回指针后 a 的值被删除了,但我不确定这是否正确

【问题讨论】:

  • let pointer = (&amp;a) as *const _;

标签: pointers rust


【解决方案1】:

我认为问题的出现是因为在函数返回指针后 a 的值被删除了,但我不确定这是否正确

嗯,是的,差不多。函数的局部变量只存在于该函数的范围内(这就是为什么如果你尝试返回一个 reference 到函数局部数据,rustc 会拒绝编译),所以get_pointer 返回一个悬空指针, 序列化和反序列化指针实际上什么都不做,ptr::read 是 UB:

安全

如果违反以下任何条件,则行为未定义:

  • src 必须对读取有效。
  • src 必须正确对齐。如果不是这种情况,请使用 read_unaligned。
  • src 必须指向正确初始化的 T 类型值。

使用 miri 运行程序会明确标记问题:

error: Undefined Behavior: pointer to alloc1416 was dereferenced after this allocation got freed
   --> /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:703:9
    |
703 |         copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pointer to alloc1416 was dereferenced after this allocation got freed
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
            
    = note: inside `std::ptr::read::<i32>` at /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:703:9
note: inside `main` at src/main.rs:12:17
   --> src/main.rs:12:17
    |
12  |         let b = ptr::read(decoded);
    |                 ^^^^^^^^^^^^^^^^^^

我实际上是想了解如何使用带有 rust 的指针来存储和加载数据

那样做是一个糟糕的主意,你正在进入 UB 领域,这意味着 所有的赌注都没有,你观察到的(在你可以观察到任何东西的范围内)已经与定义的语义没有关系。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-01
    • 1970-01-01
    • 2013-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多