正在将原始指针的目标安全地移动到 Rust

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

我正在 Rust 中创建一个双向图,父指针是 Rust 借用规则的一个明显问题,因此我使用了理论上安全的原始指针,因为父指针拥有子指针并且不能在子指针之前删除。我(在我脑海中)唯一的问题是图表何时移动。如果图形移动,所有父指针都应该无效,因为它们指向图形的旧位置。

但是通过示例测试向我展示了不同的结果。不仅旧指针仍然有效,调试器还在“寄存器>有效地址”中显示一个新条目,该条目将旧指针映射到新位置。 我的测试代码:

fn main() -> Result<()> {

    let m = test();
    println!("MT:{}, IT:{}, PTR_MT:{}", m.j, m.inner.i, unsafe {(*m.inner.parent).j});
    Ok(())
}


fn test() -> Box<MyType> {
    let mut mytype = MyType { inner: MyInnerType { parent: std::ptr::null_mut(), i: 5 }, j:69 };
    println!("MT:{}, IT:{}", mytype.j, mytype.inner.i);
    mytype.inner.parent = &mut mytype;

    Box::new(mytype)
} 


struct MyType {
    inner: MyInnerType,
    j:i32
}

struct MyInnerType {
    parent: *mut MyType,
    i:i32
}

此行为是否已定义并且我可以依赖它工作吗?

rust undefined-behavior raw-pointer
1个回答
0
投票

不,这不安全。它是不健全的并且表现出未定义的行为。 “程序按预期运行”是一种可能的结果,但不是唯一的结果。

Box::new(mytype)
mytype
移动到堆分配中,这不是 UB。然而,稍后评估
*m.inner.parent
会导致 UB,因为指针目标已移动。

您通常应该避免在 Rust 中使用原始指针,除非您要在它们之上实现安全抽象,或者您正在使用 FFI 并且如果没有它们就无法完成您需要的任务。

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