4

我一直在阅读有关此主题的不同文章/页面,终于来到了这篇文章,这让我感到困惑!

在文章中,它提到,Value Types always go where they were declared作者的意思是,值类型可以驻留在堆栈或堆中,取决于它们的声明方式/位置。

让我放一段代码片段让自己更清楚:

public class Test
{
    int testInt;
    string testString;
}

int anInt;
string aString;
Test testObj;
testObj = new Test();

执行这些代码行后,内存分配将如下所示:

在此处输入图像描述

该结构testInt存储在堆中,因为它是在Test类中声明的。

记住这个例子,让我们看一个简单的 Form.cs 代码,后面我声明一个整数。

using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public int anotherInt;
    }
}

我的困惑部分:

在这种情况下,anotherInt分配到哪里?堆栈还是堆?从表面上看,我认为大多数答案都是“堆栈”。但是,这个变量不是在一个名为的类中声明的Form1吗?那么,根据上面的第一个代码片段,它不应该进入堆吗?如果是,那么在什么情况下将结构分配给堆栈?仅当它在方法内声明时?但是,一个方法难道不是属于一个类,它又应该存储在一个堆中吗?

很多问题我都知道!但只是想知道发生了什么。我希望我的问题很清楚。

4

2 回答 2

2

在您的示例anotherInt中将分配给堆。这是因为anotherInt是 的一个字段Form1,它是一个堆分配的对象。堆栈与线程相关联,并且仅包含当前执行代码所需的引用/对象。因此,要回答有关课程下方法的问题,您在那里并不完全正确。

虽然方法属于一个类,但它们是可执行的代码块,而不是与类直接关联的内存块(就是这样anotherInt)。检查此类分配的最佳方法之一是使用 WinDbg 之类的内存调试器并实际检查您的线程堆栈与堆。这将使您最清楚地了解特定结构的实际分配位置。

在极其简化的意义上:堆栈 = 当前执行代码堆栈所需的地址,堆 = 其他所有内容。但是最后的 Jon B 出现在他与 Eric 博客的链接上。你真的不需要知道你的对象分配在哪里。

编辑:包括博客链接。

于 2012-12-18T15:49:30.170 回答
2

在您的示例anotherInt中,将与实例的其余部分一起位于堆上Form1(当然,假设您创建了一个)。

要创建局部 int,必须在方法或属性中声明变量。例如

void Foo()
{
    int localInt = 42;
}

现在,仅仅因为在方法中声明了值类型并不一定意味着它会进入堆栈。例如,捕获的变量的处理方式不同。

于 2012-12-18T15:57:02.373 回答