docs for slice::from_raw_parts警告程序员用正确的生命周期注释切片.我假设,给定一些生命周期'a,我可以用

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

我也认为

  • 因为myslice是一个引用,所以它与ptr指向的基础数据的分配/解除分配无关.生命周期注释不会影响数据的内存管理.
  • myslice本身的内存管理(即包含指针和大小的 struct )没有什么棘手的地方.它就像其他任何 struct 或i32一样.如果我把它放在Box中,那么std::raw::slice struct 将在Box死后被释放.当然,切片引用的数据不会被释放.生存期不会影响片的内存管理.

为什么正确的人生观很重要?在设置切片生命周期 时,释放后使用是唯一需要担心的危险吗?

推荐答案

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

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

请注意,在第二个函数的签名中,生命周期是正确的,释放后使用不是(立即的)危险.但可变别名非常隐蔽.基本上,一切都依赖于保证不存在可变别名,以防止出现诸如竞争条件、迭代器失效、逻辑错误以及在免费后使用(从managed byT)之类的问题.使用可变别名,几乎可以引发任何可以想象的问题.

Rust相关问答推荐

包含嵌套 struct 的CSV

在Rust中有没有办法在没有UB的情况下在指针和U64之间进行转换?

具有多个键的 HashMap

如何迭代存储在 struct 中的字符串向量而不移动它们?

Boxing 如何将数据从堆栈移动到堆?

如何在Rust中使用Serde创建一个自定义的反序列化器来处理带有内部标记的枚举

Rust 编译器不统一在 if let 表达式的分支中都 impl Future 的类型

有什么办法可以追踪泛型的单态化过程吗?

Some(v) 和 Some(&v) 有什么区别?

内部值发生变化时 Rc 的行为

类型判断模式匹配panic

为什么允许重新分配 String 而不是 *&String

从现有系列和 map 值创建新系列

为什么在 macOS / iOS 上切换 WiFi 网络时 reqwest 响应会挂起?

在 Traits 函数中设置生命周期的问题

你能用 Rust 和 winapi 制作 Windows 桌面应用程序吗?

Rust 生命周期:不能在方法内重新borrow 可变字段

为什么这个 Trait 无效?以及改用什么签名?

在传输不可复制的值时实现就地枚举修改

为什么当borrow 变量发生变化时,borrow 变量不会改变?