如何在堆中分配值类型数组?

Ash*_*mal 0 c# arrays heap struct value-type

我读了一些类似问题的答案,但我的问题没有什么不同,因为我不理解在书中写的关于这个问题的陈述.

因为struct是值类型,所以每个实例都不需要在堆上实例化对象; 这在创建类型的许多实例时会产生有用的节省.例如,创建值类型的数组只需要一个堆分配.

我的意思是数组如何只需要一个堆分配?...或单个堆分配是什么意思

Joe*_*orn 5

首先,让我们澄清"堆"与"堆栈"的含义.

今天的大多数编程环境都是基于堆栈的.在运行程序时,每次调用方法时,新条目都会被推送到为程序提供的特殊堆栈中.此堆栈条目(或框架)告诉系统在哪里查找方法的可执行代码,传递了什么参数,以及在方法退出后确切地在调用代码中返回的位置.当方法完成时,它的条目将从堆栈中删除(弹出),因此程序可以返回到前一个方法.当堆栈为空时,程序已完成.

堆栈上的每个帧也具有用于该方法的局部变量的一定量的空间,并且堆栈本身具有有限的大小.这就是"Stack Overflows"的来源.太深入了解太多的方法调用,堆栈将耗尽空间.

另一方面,堆是不会自动授予程序的内存.它是程序必须要求的内存,超出它的核心分配.必须更仔细地管理堆内存,但是(通常)可用的内存更多.因为它必须由操作系统根据请求授予,所以来自堆的初始分配也比来自堆栈的分配慢一点.

作为一个广泛的概括,我们说引用类型是在堆上分配的,值类型是在堆栈上分配的(尽管有很多例外).

既然我们已经理解了这一点,我们就可以开始研究数组了.

核心数组类型本身是引用类型.我的意思是,对于任何给定的类型T,Tmay(或可能不是)是值类型,但T[]始终是引用类型.在"堆栈与堆"上下文中,这意味着即使T是值类型,创建新数组也是堆分配.数组也有固定的大小.单个堆分配将为数组中的所有元素创建足够的空间.

值类型的另一个特性是它们具有基于成员的固定大小.因此,对于数组,我们有固定数量的元素,每个元素都具有已知的固定大小.这足以获得数组对象的所有空间以及单个堆分配中的元素.每个项目的都保存在阵列的核心内存中.

对于包含引用类型的数组,数组的堆分配仅为引用创建空间.要填充数组,必须为每个元素进行额外分配.

具有一个或多个引用类型成员的值类型可能会略微复杂化.在这种情况下,值类型的空间被分配为正常,但引用成员的值的一部分只是一个引用.它仍然需要单独的分配来为这些引用成员创建对象.