为什么life :: from_raw_parts的生命周期很重要?

时间:2015-10-23 15:02:21

标签: rust ffi lifetime

User ID | Connection Date 1 | 12/10/2011 2 | 12/12/2011 1 | 12/14/2011 3 | 12/15/2011 1 | 12/16/2011 2 | 12/17/2011 2 | 12/18/2011 1 | 12/19/2011 3 | 12/20/2011 4 | 12/21/2011 2 | 12/21/2011 的文档警告程序员使用正确的生命周期注释切片。我假设,给定一些生命周期slice::from_raw_parts,我可以使用

执行此注释
'a

我也认为

  • 由于let myslice: &'a mut [i32] = std::slice::from_raw_parts_mut(ptr, sz) 是引用,因此它与ptr指向的基础数据的分配/释放无关。生命周期注释不会影响数据的内存管理。
  • myslice本身的内存管理(即包含指针和大小的结构)并没有什么棘手的问题。它就像任何其他结构或myslice一样。如果我将它放在i32中,那么当Box死亡时,std::raw::slice结构将被取消分配。当然,切片引用的数据不会被解除分配。生命周期不会影响切片的内存管理。

为什么让生命保持正确至关重要?在设定切片寿命时,使用后是免费的唯一危险吗?

2 个答案:

答案 0 :(得分:9)

使用后免费是唯一的危险。如果生命周期错误,可能会导致可变别名。让我们以这个(人为的)函数为例:

fn duplicate_mut_slice<'a, T>(xs: &mut [T]) -> &'a mut [T] {
    let ptr = xs.as_mut_ptr(); // btw, this part is safe!
    unsafe { std::slice::from_raw_parts_mut(ptr, xs.len()) }
}

由于生命周期如何排列,这样的调用将会成功:

fn alias_first_element<T>(xs: &mut [T]) -> (&mut T, &mut T) {
    let a = duplicate_mut_slice(xs);
    let b = duplicate_mut_slice(xs);
    (&mut a[0], &mut b[0])
}

请注意,在第二个函数的签名中,生命周期是正确的,并且释放后使用不是(立即)危险。但可变别名是非常阴险的。基本上所有东西都依赖于保证不存在可变别名,以防止诸如竞争条件,迭代器失效,逻辑错误以及实际上使用后( T管理的事情)等问题。您可以使用可变别名来解决几乎任何可以想到的问题。

答案 1 :(得分:0)

更新:正如delnan所说,可变别名是一个真正的问题,可能因设置不正确的生命周期而产生。有关详细信息,请参阅他/她的回答。

旧答案

自由使用确实是设置切片寿命时唯一的恐惧危险。只要您指定的生命周期,编译器就会信任您并假设切片指向的数据存在。如果您的带注释的生命周期长于基础数据的实际生命周期,您最终可能会遇到使用后免费的错误(您可以在数据已被解除分配时使用切片)。

关于你的假设,它们是正确的。生命周期注释不会对数据的内存管理产生任何影响。

相关问题