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