我想了解 from_pointer 的行为方式。
&'static
是什么意思? &'static T
的使用寿命会比瞄准镜更长吗?
反正都是不安全的。寿命由赋予 to_pointer
的值设置。我只是想知道如果我创建大量对同一项目的引用,它会如何表现。
如果我有这样的东西:
let pointer = to_pointer(&string);
for _ in 0..999999 {
let value = from_pointer(pointer);
println!("{value}")
}
会导致内存泄漏吗?值是在右括号中处理的还是会创建大量从未处理过的引用?
fn to_pointer<T>(value: &T) -> *const T {
value as *const T
}
fn from_pointer<T>(pointer: *const T) -> &'static T {
unsafe { &*pointer }
}
这个也一样。
T: 'static
有什么作用。会导致内存泄漏吗?我的猜测是它与 from_pointer 相同
pub struct Pointer<T>(*const T);
impl<T: 'static> Deref for Pointer<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { &*self.0 }
}
}
天哪。这里有很多东西需要解压。
是什么意思?&'static
的使用寿命会比示波器长吗?&'static T
具有
'static
生命周期的引用表示引用对象的生存期为正在运行的程序的剩余生命周期。原始指针不具有编译器可用于执行借用检查的生命周期,因此您能够从它们创建&'static
引用,不意味着这是正确或有效的。
会导致内存泄漏吗?
我认为您错误地使用了术语“内存泄漏”。当分配的内存不再使用或需要但从未释放时,就会发生内存泄漏。我认为您可能想问的是“悬空指针”,这几乎是完全相反的:指向已释放内存的指针。引用已释放的内存是未定义的行为。
值是否已在右括号中释放,或者这会创建大量从未释放的引用吗?返回时,当
value
to_pointer
确实被丢弃;然而,在这种情况下,value
只是T
的参考。删除引用不会删除所指对象,因此在 T
返回后,to_pointer
仍将位于其内存位置。但是,由于您的 from_pointer
创建了
&'static T
,而 T
不能保证在 'static
生命周期内保持有效,因此它是不正确的。更好的版本可能如下所示:/// # Safety
/// `pointer` must be valid for shared reads for the `'a` lifetime
unsafe fn from_pointer<'a, T>(pointer: *const T) -> &'a T {
&*pointer
}
这样调用
from_pointer
是不安全的操作,调用者需要满足安全保证。
T: 'static
有什么作用
T: 'static
仅将可以实例化泛型参数的类型限制为仅具有
'static
借用(或更长,不存在)的类型。它不保证指针有效,因此 Deref
的实现是不正确的。更好的版本可能看起来像:impl<T> Pointer<T> {
/// # Safety
/// The pointer must be valid for shared reads for the `'a` lifetime
unsafe deref<'a>(&self) -> &'a T {
&*self.0
}
}
与以前一样,维护安全保证的责任就被推给了调用者。请注意,此处不能使用
Deref
特征,因为该特征的用户不会被迫遵守其保证。您可以想象在其位置定义一个
unsafe trait
,但它不会具有编译器为 Deref
提供的特殊状态(例如,用于自动取消引用或 *
引用运算符)。