存储函数变量的位置?在堆栈或堆上?

时间:2014-03-16 01:27:15

标签: c# .net stack heap managed

当一个程序调用一个函数时,哪种类型的数据结构是为该函数中的变量分配的内存?堆还是堆?为什么呢?

在我看来,它应该存储在堆栈上,因为它们不一定是引用类型。但是,在我读到答案的地方,声明它们存储在堆上并且在函数返回值后自由。

4 个答案:

答案 0 :(得分:3)

它比这复杂一点,并且使用堆栈和堆的事实实际上是实现细节。谈论数据的生命周期更有意义。短期数据将存储在堆栈(或寄存器)中。长期存在的数据存储在堆上。

引用类型的实例始终被认为是长期存在的,因此它们会在堆上运行。值类型可以是两者。本地值类型通常存储在堆栈中,但如果某些内容将此类变量的生命周期延长到超出函数范围,则将其存储在堆栈中是没有意义的。捕获的变量会发生这种情况,即使它们是值类型,它们也会存储在堆上。

答案 1 :(得分:1)

在调用函数之前将参数推送到堆栈。如果参数是值类型,则可以直接存储它们。如果它们是引用类型,则它们存储在堆中,并且指向内存位置的指针被压入堆栈。当函数返回时,值会从堆栈弹出,最终垃圾收集器会注意到堆上的内存不再有指向它的指针,并且也会清理它。

答案 2 :(得分:1)

您应该阅读这篇文章:http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx

在Eric Lippert自己的话中:

  

"在桌面CLR的Microsoft实现C#中,值类型   当值是局部变量或时,存储在堆栈中   临时的,不是lambda或的一个封闭的局部变量   匿名方法,方法体不是迭代器块,而且   抖动选择不注册该值。"

答案 3 :(得分:0)

(已编辑)如果函数中的变量是引用类型,则引用将在堆栈上分配,但它们的关联对象将在堆上。但如果它们是值类型,则分配的内存将位于堆栈中。 (虽然我不是100%肯定的。)

例如,请考虑以下代码。

public int myMethod(int x, int y, int z)
{
    double money;
    myClass myObjectRef = new myClass();
    return x + y + z;
}

在上面的方法中,变量x,y,z和myObjectRef将在堆栈上创建,但由“new myClass()”语句生成的对象将在堆上。