【问题标题】:Is it valid to store a reference whose lifetime has expired, if the referenced object is still alive?如果引用的对象仍然存在,存储其生命周期已过期的引用是否有效?
【发布时间】:2022-11-30 22:15:54
【问题描述】:

存储生命周期绑定对象(通过原始指针)以供将来 FFI 调用使用是否有效?

这是一个最小的示例:

struct X(u32);
struct Data<'a> {
    x: &'a mut X,
}

fn create(x: &mut X) -> Data<'_> {
    Data { x }
}

fn main() {
    // Our referenced object, guaranteed not to be destroyed during FFI calls
    let mut x = X(42);

    // First FFI call (just a normal call for this sample)
    let ptr = {
        let xref = &mut x; // start of 'a
        let data = create(xref);
        Box::into_raw(Box::new(data))
        // end of 'a
    };
    // ptr is returned to the C world

    // Next FFI call, convert the raw pointer back
    let data = unsafe { Box::from_raw(ptr) };

    // data stores a field having type &'a mut X
    // but the lifetime of the reference it holds ('a) has theoretically expired
    // even if X is guaranteed to still be alive

    // This "works", but is it valid?
    dbg!(data.x.0);
}

假设我们可以保证:

  • x 对所有 FFI 调用有效(因此引用始终指向有效对象)
  • 无法从安全 Rust 获得对 x 的 2 个引用

代码有效吗?

或者引用生命周期的“到期”是否足以使代码无效?如果是这样,是否可以证明这一点(例如通过产生内存损坏)?

【问题讨论】:

    标签: rust lifetime


    【解决方案1】:

    生命周期只是编译时的概念,借用的“过期”对于不安全代码来说无关紧要。如果您确保持有借用规则(共享异或可变,并且对象未被释放),即使在其生命周期“过期”之后,您也可以安全地使用该引用。

    【讨论】:

    • “Lifetimes are a compile-time-only concept”:当然,但是编译时的概念理论上可以允许一些优化,如果不安全代码违反了基本假设,这些优化可能会变得无效。您的意思是,违反生命周期语义无关紧要(前提是共享异或可变 + 有效对象(如果有保证)),对吗?
    猜你喜欢
    • 1970-01-01
    • 2012-02-19
    • 2014-10-28
    • 2015-09-03
    • 2019-12-18
    • 2020-09-19
    • 2019-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多