2

我已经搜索了一段时间,但对于为什么值类型必须分配在堆栈上而引用类型(即动态内存或对象必须驻留在堆上)没有明确的答案。为什么不能在堆栈上分配相同的内容?

4

5 回答 5

4

他们可以。实际上,这并不是因为堆栈通常是比堆更稀缺的资源,并且在堆栈上分配引用类型可能会很快耗尽它。此外,如果一个函数返回分配在其堆栈上的数据,它将需要在调用者方面复制语义,否则可能会返回将被下一个函数调用覆盖的内容。

值类型,通常是局部变量,可以使用本地机器指令快速轻松地引入和带出范围。返回值类型的复制语义是微不足道的,因为最适合机器寄存器。这种情况经常发生,应该尽可能便宜。

于 2010-06-17T17:27:33.600 回答
1

值类型总是存在于堆栈中是不正确的。阅读 Jon Skeet 关于该主题的文章:

.NET 中的内存 - 去哪里

于 2010-06-17T17:28:02.623 回答
1

我了解堆栈范例(嵌套分配/解除分配)无法处理某些需要非嵌套对象生命周期的算法。

就像静态分配范式不能处理递归过程调用一样。(例如,将 fibonacci(n) 计算为 f(n-1) + f(n-2))

不过,我不知道有一个简单的算法可以说明这一事实。任何建议,将不胜感激 :-)

于 2010-07-07T13:52:39.083 回答
0

当方法退出时,方法放入堆栈的任何内容都将消失。在 .net 和 Java 中,如果一个类对象在对它的最后一个引用消失后就消失了,这是完全可以接受的(实际上是可取的),但是如果一个对象在对它的引用仍然存在时消失,那将是致命的。在一般情况下,编译器不可能知道,当一个方法创建一个对象时,对该对象的任何引用在方法退出后是否会继续存在。如果没有这样的保证,分配类对象的唯一安全方法是将它们存储在堆上。

顺便说一句,在 .net 中,可变值类型的一个主要优点是它们可以通过引用传递,而不会放弃对它们的永久控制。如果类 'foo' 或其方法具有结构 'boz',其中 foo 的方法之一通过引用方法 'bar' 传递,则 bar 或其调用的方法可以做任何他们想做的事情' boz' 直到它们返回,但是一旦 'bar' 返回它对 'boz' 的任何引用都将消失。这通常会导致比用于类对象的混杂可共享引用更安全和更清晰的语义。

于 2011-09-26T23:31:43.970 回答
0

局部变量在堆栈中分配。如果不是这种情况,那么在分配变量的内存时,您将无法让变量指向堆。如果需要,您可以在堆栈中分配东西,只需在本地创建一个足够大的缓冲区并自己管理它。

于 2010-06-17T17:26:55.380 回答