简体   繁体   English

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

[英]Why is the lifetime important for slice::from_raw_parts?

The docs for slice::from_raw_parts warn the programmer to annotate the slice with the correct lifetime. slice::from_raw_parts的文档警告程序员使用正确的生命周期注释切片。 I assume that, given some lifetime 'a , I can perform this annotation with 我假设,给定一些生命周期'a ,我可以执行此注释

let myslice: &'a mut [i32] = std::slice::from_raw_parts_mut(ptr, sz)

I also assume that 我也认为

  • Since myslice is a reference, it has nothing to do with the allocation/deallocation of the underlying data pointed to by ptr. 由于myslice是一个引用,它与ptr指向的底层数据的分配/释放无关。 The lifetime annotation doesn't affect the memory management of the data. 生命周期注释不会影响数据的内存管理。
  • There's nothing tricky about memory management for myslice itself (ie a struct containing a pointer and a size). 关于myslice本身的内存管理(即包含指针和大小的结构)并没有什么棘手的问题。 It's just like any other struct or i32 . 它就像任何其他结构或i32 If I put it in a Box , then the std::raw::slice struct will get deallocated when the Box dies. 如果我将它放在Box ,那么当Box死亡时, std::raw::slice结构将被释放。 The data referred to by the slice will not get deallocated, of course. 当然,切片引用的数据不会被解除分配。 The lifetime doesn't affect the memory management for the slice. 生命周期不会影响切片的内存管理。

Why is it important that I get the lifetime correct? 为什么让生命保持正确至关重要? Is use-after-free the only danger to fear when setting the slice lifetime? 在设定切片寿命时,使用后是免费的唯一危险吗?

Use-after-free is not the only danger. 免费使用并不是唯一的危险。 With the wrong lifetime, one can cause mutable aliasing. 如果生命周期错误,可能会导致可变别名。 Let's take this (contrived) function as an example: 我们以这个(人为的)函数为例:

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

Because of how the lifetimes line up, calls like this will succeed: 由于生命周期如何排列,这样的调用将会成功:

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

Note that in this second function's signature, the lifetimes are correct and use-after-free is not an (immediate) danger. 请注意,在第二个函数的签名中,生命周期是正确的,并且释放后使用不是(立即)危险。 But mutable aliasing is very insidious. 但可变别名是非常阴险的。 Basically everything relies on the guaranteed absence of mutable aliasing to prevent problems like race conditions, iterator invalidation, logic errors and indeed use-after-free (of something managed by the T ). 基本上所有东西都依赖于保证缺少可变别名以防止诸如竞争条件,迭代器失效,逻辑错误以及确实使用后( T 管理的事物)之类的问题。 You can cause almost any problem imaginable with mutable aliasing. 您可以使用可变别名导致几乎任何可以想象的问题。

UPDATE: as delnan stated, mutable aliasing is a real problem that may arise from setting an incorrect lifetime. 更新:正如delnan所说,可变别名是一个真正的问题,可能因设置不正确的生命周期而产生。 See his/her answer for more details. 有关详细信息,请参阅他/她的回答。

Old answer 老答案

Use-after-free is indeed the only danger to fear when setting the slice lifetime. 在设置切片寿命时,释放后使用确实是唯一可怕的危险。 The compiler will trust you and assume the data pointed by the slice lives as long as the lifetime you specify. 只要您指定的生命周期,编译器就会信任您并假设切片指向的数据存在。 In case your annotated lifetime is longer than the real lifetime of the underlying data, you may end up with use-after-free bugs (you will be able to use the slice while the data has already been deallocated). 如果您的带注释的生命周期长于基础数据的实际生命周期,您最终可能会遇到使用后释放的错误(您可以在数据已被解除分配时使用切片)。

Regarding your assumptions, they are correct. 关于你的假设,它们是正确的。 Lifetime annotations don't have any effect on the memory management of the data. 生命周期注释对数据的内存管理没有任何影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM