我对如何处理内存的数组有一些问题的理解。我很难用语言解释,所以我会给你写一些代码:)
string[] arr1 = new string[10];
string[] arr2 = new string[10];
/* Fill 'arr1' with random strings */
for(int i = 0; i < 10; i++)
{
arr2[i] = arr1[i]
}
这会占用2倍(arr1和arr2中的字符串大小)吗?
最初答案对我来说似乎很明显“不”,但后来我记得那个带有所有元素的数组存储在大量连续的内存中以便快速编制索引,所以目前我不知道:)
答案 0 :(得分:7)
是的,与单个数组相比,它将占用内存的两倍,数组对象实例和它们占用的内存是完全分开的。
由于string
是引用类型,因此每个数组将存储10个字符串引用。引用类似于指针,因为它们只包含一个描述(“引用”),用于在内存中查找实际的对象实例(例如内存地址)。
这意味着arr1
和arr2
的引用实际上指向示例中相同的10个字符串实例(因为您只是复制引用)。
对于另一方面包含值类型的数组(例如,任何基本类型或struct
),数组占用一个大块中数组中所有项所需的完整连续内存空间 - 每个值类型需要为它包含的字段空间很大。
答案 1 :(得分:7)
第一个数组包含十个对字符串的引用,因此需要内存来保存它们。这同样适用于第二个数组。
但字符串是分开存储的。如果将字符串从一个数组复制到另一个数组,则不会分配额外的内存。
因此,在您的情况下,消耗的总内存是(忽略开销):
arr1
arr2
答案 2 :(得分:4)
您已经分配了2个数组,因此每个数组都将在内存中占用自己的空间。因此,回答你的问题是肯定的。
但是,你还必须考虑在这里分配两次。 string
是一种引用类型,因此通过执行arr2[i] = arr1[i]
代码,您只是复制对该字符串的引用。因此,您总共有20个引用,但是有10个不同的字符串,这些字符串被分配一次。
答案 3 :(得分:2)
这取决于数组中的内容。 .NET中引用类型的数组实际上是引用数组(指针),因此数组本身不包含字符串。 .NET中的字符串是引用类型,因此您的示例特别适合解释这一点。
以此为例:
string[] arr1 = new string[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J" };
string[] arr2 = new string[10];
/* Fill 'arr1' with random strings */
for(int i = 0; i < 10; i++)
{
arr2[i] = arr1[i]
}
变量arr2将额外增加10个引用内存+一点开销,但它不会存储所有字符串的新副本。另一方面,这将使用Copy方法创建新字符串,因此将占用更多内存:
string[] arr1 = new string[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J" };
string[] arr2 = new string[10];
/* Fill 'arr1' with random strings */
for(int i = 0; i < 10; i++)
{
arr2[i] = arr1[i].Copy();
}
答案 4 :(得分:2)
您将需要空间来存储两个数组中的引用,以及用于存储引用引用的对象的空间。在您的示例中,每个字符串只有一个副本,但每个字符串有两个副本(内存地址指针)。字符串可能非常大,但(重复的)引用会小得多。