C# 拥有两个相同的数组需要两倍的内存吗?
我在理解数组如何处理内存方面有点问题。我不擅长用文字解释,所以我会给你写一些代码:)C# 拥有两个相同的数组需要两倍的内存吗?,c#,.net,arrays,memory,indexing,C#,.net,Arrays,Memory,Indexing,我在理解数组如何处理内存方面有点问题。我不擅长用文字解释,所以我会给你写一些代码:) string[]arr1=新字符串[10]; 字符串[]arr2=新字符串[10]; /*用随机字符串填充“arr1”*/ 对于(int i=0;i
string[]arr1=新字符串[10];
字符串[]arr2=新字符串[10];
/*用随机字符串填充“arr1”*/
对于(int i=0;i<10;i++)
{
arr2[i]=arr1[i]
}
这需要2倍(arr1和arr2中字符串的大小)的内存吗?
起初,我觉得答案似乎很明显是“不”,但后来我记得数组及其所有元素都存储在一大块连续的内存中,用于快速索引,所以目前我不知道:)是的,与单个数组相比,它需要两倍的内存,数组对象实例及其占用的内存是完全独立的 由于
string
是引用类型,每个数组将存储10个字符串引用。引用类似于指针,因为它们只包含一个描述(“引用”),在该描述中可以找到内存中的实际对象实例(例如内存地址)
这意味着arr1
和arr2
具有实际指向示例中相同的10个字符串实例的引用(因为您只是复制引用)
另一方面,对于包含值类型的数组(例如,任何基元类型或
struct
),数组占用一个大数据块中数组中所有项所需的全部连续内存空间-每个值类型所需的空间与其包含的字段相同。是的,与使用单个数组相比,它将占用两倍的内存,数组对象实例及其占用的内存是完全独立的
由于string
是引用类型,每个数组将存储10个字符串引用。引用类似于指针,因为它们只包含一个描述(“引用”),在该描述中可以找到内存中的实际对象实例(例如内存地址)
这意味着arr1
和arr2
具有实际指向示例中相同的10个字符串实例的引用(因为您只是复制引用)
另一方面,对于包含值类型的数组(例如,任何基元类型或
struct
),数组占用一个大块中数组中所有项所需的全部连续内存空间-每个值类型需要与其包含的字段一样多的空间。,这取决于数组中的内容。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]
}
string[]arr1=新字符串[]{“A”、“B”、“C”、“D”、“E”、“F”、“G”、“H”、“I”、“J”};
字符串[]arr2=新字符串[10];
/*用随机字符串填充“arr1”*/
对于(int i=0;i<10;i++)
{
arr2[i]=arr1[i]
}
变量arr2将额外占用10个参考值的内存+一点开销,但它不会存储所有字符串的新副本。另一方面,这将使用该方法创建新字符串,因此将占用大量内存:
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();
}
string[]arr1=新字符串[]{“A”、“B”、“C”、“D”、“E”、“F”、“G”、“H”、“I”、“J”};
字符串[]arr2=新字符串[10];
/*用随机字符串填充“arr1”*/
对于(int i=0;i<10;i++)
{
arr2[i]=arr1[i]。复制();
}
这取决于阵列中的内容。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]
}
string[]arr1=新字符串[]{“A”、“B”、“C”、“D”、“E”、“F”、“G”、“H”、“I”、“J”};
字符串[]arr2=新字符串[10];
/*用随机字符串填充“arr1”*/
对于(int i=0;i<10;i++)
{
arr2[i]=arr1[i]
}
变量arr2将额外占用10个参考值的内存+一点开销,但它不会存储所有字符串的新副本。另一方面,这将使用该方法创建新字符串,因此将占用大量内存:
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();
}
string[]arr1=新字符串[]{“A”、“B”、“C”、“D”、“E”、“F”、“G”、“H”、“I”、“J”};
字符串[]arr2=新字符串[10];
/*用随机字符串填充“arr1”*/
对于(int i=0;i<10;i++)
{
arr2[i]=arr1[i]。复制();
}
您将需要在两个数组中存储引用的空间,以及存储这些引用引用的对象的空间。在您的示例中,每个字符串只有一个副本,但每个字符串的引用(内存地址指针)有两个副本。字符串可能非常大,但(重复的)引用将小得多。您将需要在两个数组中存储引用的空间,以及存储这些引用所引用的对象的空间。在您的示例中,每个字符串只有一个副本,但每个字符串的引用(内存地址指针)有两个副本。字符串可能非常大,但(重复的)引用将小得多。您已经分配了2个数组,因此每个数组将占用内存中自己的空间。所以,你的问题的答案是肯定的
<>但是,你也必须考虑在这里被分配两次。code>string是一种引用类型,因此通过执行
arr2[i]=arr1[i]
code,您只是将引用复制到该字符串。因此,您总共有20个引用,但10个不同的字符串只分配了一次。您分配了2个数组,因此每个数组都将占用自己的内存空间。所以,你的问题的答案是肯定的
<>但是,你也必须考虑在这里被分配两次。code>string是一种引用类型,因此通过执行arr2[i]=arr1[i]
code,您只是将引用复制到该字符串。