所以我理解这个工作原理的简单答案是本地的东西发生在堆栈中,盒子里的东西发生在堆上 .
但是,当您有更复杂的行为时会发生什么?
具体来说,让我们谈谈在FFI中保存了不确定时间的数据,然后必须从* mut c_void中复活 .
如果你'忘记'一个指针,使用std :: mem :: forget或std :: mem :: transmute()一个指向* const指针的指针结果是多么持久?
如果(例如)这是在函数内完成然后函数返回,堆栈是否被清除并且内存变为无效?
堆积分配的“Box”指针通常是否有效直到它们被销毁(例如使用read())?
我在IRC上被告知,这通常是正确的方法:
unsafe fn fp(v:Box<Foo>) -> *const c_void {
return transmute(foo);
}
但是,看看libcore :: raw :: Box,Box与* const T并不是一样的;那真的好吗?
1 回答
如果通过
fp
函数转换Box
和transmute,只要您愿意,指针将保持有效,因为transmute
正在消耗该值,因此释放内存的析构函数不会运行 . (至少,它是有效的,直到你将它转换回Box<...>
让析构函数运行并释放内存 . )forget
没有返回值,它只是在不运行析构函数的情况下丢弃该值 .但请注意,转换为
*const c_void
需要额外注意,例如Box<Foo>
内的Foo
可能包含线程本地数据或引用,因此可能无效在线程之间传递,或永远存在 . (意思是指针本身永远存在/可用但是你喜欢,但它指向的数据可能没有 . )如果你开始编译
&
指针,你需要非常小心生命周期并且不要让它们从它们所指向的数据范围中逃脱(例如,你不能从函数返回指向局部变量的指针) .堆栈没有被“清除”(即它没有明确归零),但是将任何指针用于不再存在的堆栈帧是无效的 .
你需要更具体,
ptr::read
不能直接在Box
上调用,而在*const c_void
上调用ptr::read
肯定不会做任何有用的事情 .raw::Box
完全不是正常Box
的表示 .raw::Box
是旧@
(现在为Gc
)类型的表示形式 .Box<T>
是literally a wrapper around a *mut T .