cut*_*lus 2 unsafe lifetime rust
我有一个使用的结构Arena:
struct Foo<'f> {
a: Arena<u64>, // from the typed-arena crate
v: Vec<&'f u64>,
}
Run Code Online (Sandbox Code Playgroud)
只要引用的生命周期受主结构体生命周期的约束,延长竞技场引用的生命周期是否安全?
impl<'f> Foo<'f> {
pub fn bar(&mut self, n: u64) -> Option<&'f u64> {
if n == 0 {
None
} else {
let n_ref = unsafe { std::mem::transmute(self.a.alloc(n)) };
Some(n_ref)
}
}
}
Run Code Online (Sandbox Code Playgroud)
有关更多背景信息,请参阅此Reddit 评论。
\n\n\n只要引用的生命周期受主结构体生命周期的约束,延长竞技场引用的生命周期是否安全?
\n
原则上,这Arena将被删除,这将是安全的,但也是不必要的,因为它已经活得足够长了。FooArena
然而,这并不是您的代码实际所做的!生命周期\'f可能比 struct \xe2\x80\x94 的生命周期更长,它可以与 中最短生命周期的引用一样长v。例如:
fn main() {\n let n = 1u64;\n let v = vec![&n];\n let bar;\n {\n let mut foo = Foo { a: Arena::new(), v };\n bar = foo.bar(2);\n // foo is dropped here, along with the Arena\n }\n // bar is still useable here because \'f is the full scope of `n`\n println!("bar = {:?}", bar); // Some(8021790808186446178) - oops!\n}\nRun Code Online (Sandbox Code Playgroud)\n\n试图假装生命周期比实际长,这为安全代码中的未定义行为创造了机会。
\n\n一个可能的解决方法是拥有 的Arena外部struct并依靠借用检查器来确保它在仍在使用时不会被丢弃:
struct Foo<\'f> {\n a: &\'f Arena<u64>,\n v: Vec<&\'f u64>,\n}\n\nimpl<\'f> Foo<\'f> {\n pub bar(&mut self, n: u64) -> Option<&\'f u64> {\n if n == 0 {\n None\n } else {\n Some(self.a.alloc(n))\n }\n }\n}\n\nfn main() {\n let arena = Arena::new();\n let n = 1u64;\n let v = vec![&n];\n let bar;\n {\n let mut foo = Foo { a: &arena, v };\n bar = foo.bar(2);\n }\n println!("bar = {:?}", bar); // Some(2)\n}\nRun Code Online (Sandbox Code Playgroud)\n\n就像您的不安全版本一样,生命周期表示对 的引用Arena必须至少与 中的项目一样长有效Vec。不过,这也证实了这个事实是真的!由于不存在不安全代码,您可以相信借用检查器这不会触发 UB。
| 归档时间: |
|
| 查看次数: |
123 次 |
| 最近记录: |