堆栈与堆分配究竟如何在Rust中工作?

时间:2014-08-15 08:47:04

标签: rust

所以我理解这个工作原理的简单答案是本地的东西发生在堆栈中,盒子里的东西发生在堆上。

然而,当你有更复杂的行为时会发生什么?

具体来说,让我们谈谈在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;那真的好吗?

1 个答案:

答案 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