gpt4 book ai didi

rust - 什么时候延长 Arenas 引用的生命周期是安全的?

转载 作者:行者123 更新时间:2023-11-29 08:12:00 24 4
gpt4 key购买 nike

我有一个使用 Arena 的结构:

struct Foo<'f> {
a: Arena<u64>, // from the typed-arena crate
v: Vec<&'f u64>,
}

只要受主结构体生命周期的约束,延长竞技场引用的生命周期是否安全?

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)
}
}
}

有关更多上下文,请参阅此 Reddit comment .

最佳答案

Is it safe to extend the lifetime of a reference into the arena so long as it is bound by the lifetime of the main struct?

Arena 将与 Foo 一起掉落,因此原则上,这是安全的,但也没有必要,因为Arena 已经活得够久了。

但是,这并不是您的代码实际执行的操作! 'f 的生命周期可以比结构体的生命周期更长——它可以与 v 中生命周期最短的引用一样长。例如:

fn main() {
let n = 1u64;
let v = vec![&n];
let bar;
{
let mut foo = Foo { a: Arena::new(), v };
bar = foo.bar(2);
// foo is dropped here, along with the Arena
}
// bar is still useable here because 'f is the full scope of `n`
println!("bar = {:?}", bar); // Some(8021790808186446178) - oops!
}

试图假装生命周期比实际长,这为安全代码中的未定义行为创造了机会。


一个可能的修复方法是在 struct 之外拥有 Arena 并依靠借用检查器来确保它在仍在使用时不会被删除:

struct Foo<'f> {
a: &'f Arena<u64>,
v: Vec<&'f u64>,
}

impl<'f> Foo<'f> {
pub bar(&mut self, n: u64) -> Option<&'f u64> {
if n == 0 {
None
} else {
Some(self.a.alloc(n))
}
}
}

fn main() {
let arena = Arena::new();
let n = 1u64;
let v = vec![&n];
let bar;
{
let mut foo = Foo { a: &arena, v };
bar = foo.bar(2);
}
println!("bar = {:?}", bar); // Some(2)
}

就像您的不安全版本一样,生命周期表示对 Arena 的引用必须至少与 Vec 中的项目一样长有效。不过,这也证实了这个事实是真的!由于不存在不安全代码,您可以相信借用检查器这不会触发 UB。

关于rust - 什么时候延长 Arenas 引用的生命周期是安全的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56420444/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com