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

Jac*_*per 8 ffi lifetime rust

用于slice::from_raw_parts警告程序员使用正确的生命周期注释切片的文档.我假设,考虑到一些生命周期'a,我可以执行此注释

let myslice: &'a mut [i32] = std::slice::from_raw_parts_mut(ptr, sz)
Run Code Online (Sandbox Code Playgroud)

我也认为

  • 由于myslice是引用,它与ptr指向的底层数据的分配/释放无关.生命周期注释不会影响数据的内存管理.
  • 关于myslice自身的内存管理(即包含指针和大小的结构)并没有什么棘手的问题.它就像任何其他结构或i32.如果我把它放在一个Box,那么std::raw::slice结构将在Box死时被释放.当然,切片引用的数据不会被解除分配.生命周期不会影响切片的内存管理.

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

小智 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()) }
}
Run Code Online (Sandbox Code Playgroud)

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

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])
}
Run Code Online (Sandbox Code Playgroud)

请注意,在第二个函数的签名中,生命周期是正确的,并且释放后使用不是(立即)危险.但可变别名是非常阴险的.基本上一切都依赖于保证没有可变走样,以防止类似的竞争条件,迭代器失效,逻辑错误的问题,确实是使用无后(的东西所管理T).您可以使用可变别名导致几乎任何可以想象的问题.