提问人:RedCrafter LP 提问时间:11/7/2023 更新时间:11/7/2023 访问量:59
在生锈中移动原始指针的目标是否安全
Is moving the target of a raw Pointer safe in rust
问:
我正在 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
}
此行为是否已定义,我可以依赖它工作吗?
答:
3赞
cdhowie
11/7/2023
#1
不,这是不安全的。它是不健全的,并表现出未定义的行为。“程序按预期工作”是一种可能的结果,但不是唯一的结果。
Box::new(mytype)
移动到堆分配中,该堆分配不是 UB。但是,稍后的评估会导致 UB,因为指针目标已被移动。mytype
*m.inner.parent
你通常应该避免在 Rust 中使用原始指针,除非你在它们之上实现一个安全的抽象,或者你正在使用 FFI,没有它们就无法完成你需要做的事情。
评论
Box::new(mytype)
mytype