函数的变量存储在哪里?在堆栈或堆上

本文关键字:堆栈 变量 存储 在哪里 函数 | 更新日期: 2023-09-27 17:50:23

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

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

函数的变量存储在哪里?在堆栈或堆上

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

引用类型的实例总是被认为是长寿命的,所以它们被放在堆上。值类型可以是这两种类型。局部值类型通常存储在堆栈中,但是如果某些东西将这种变量的生命周期扩展到函数范围之外,则将其存储在堆栈中就没有意义了。这种情况发生在捕获的变量上,即使它们是值类型,也会存储在堆上。

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

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

用Eric Lippert自己的话来说:

"在微软的c#桌面CLR上实现,值类型当值是局部变量或临时的,它不是lambda或匿名方法,并且方法体不是迭代器块,并且抖动选择不注册该值。"

(Edited)如果函数中的变量是引用类型,则引用将在堆栈上分配,但其相关对象将在堆上分配。但如果它们是值类型,则分配的内存将在堆栈上。(虽然我不是百分之百确定)。

例如,考虑以下代码:

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()"语句创建的对象将在堆上。