2010-06-17 99 views
1

我已经搜索了一段时间,但没有确定的答案是为什么值类型必须分配在栈上,而引用类型即动态内存或对象必须驻留堆。 为什么不能在堆栈上分配同样的东西?为什么堆栈和堆都需要内存分配

回答

0

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

+0

所以基本上你正在堆栈上定制托管堆。 ;) – 2010-06-17 17:27:54

+0

@bjarkef - 嘿,一个人不得不做的事:) – 2010-06-17 17:28:21

3

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

通过本地机器指令,可以快速方便地将值类型(通常为本地变量)引入和取消范围。复制返回值类型的语义是微不足道的,因为它最适合于机器寄存器。这经常发生,应该尽可能便宜。

1

我明白堆栈范式(嵌套的分配/释放操作)不能处理这需要非嵌套的对象生命周期某些算法。

就像静态分配范式无法处理递归过程调用。 (例如斐波纳契(n)的天真计算为f(n-1)+ f(n-2))

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

0

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

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