C# 中锯齿状数组的内存分配与 C++ 中二维数组的内存分配

Memory allocation of Jagged arrays in C# vs 2d arrays memory allocation in C++

我有一个关于 C# 中的锯齿状数组的问题,因为我在互联网上的某个地方读到关于锯齿状数组的信息,我认为 C# 中二维锯齿状数组的内存分配与 C++ 中二维数组的内存分配相同,因为 2d Jagged 数组有一个指针数组,每个指针指向一个元素数组(例如整数元素)我的意思是 C++ 中数组的内存分配:

int** twoDArr {new int* [number1]};
for (int i = 0; i < number1; i++)
{
   twoDArr[i] = new int[number2];
}

与C#中2d Jagged数组的内存分配相同:

int[][] 2DJaggedArray = new int[number1][];
for (int i = 0; i < 2DJaggedArray.GetLength(0); i++)
{
    2DJagggedArray[i] = new int[number2];
}

但我不确定,所以你能告诉我我是否正确吗?如果是这样,你能解释一下 C# 中二维数组的内存分配方式吗,例如下面的数组:

int[,] 2DArray = new int[number1,number2];

谢谢。

是的,你是对的。 C# 中的锯齿状数组基本上是内存中的一维数组,其中每个元素只是一个引用。当您在 for 循环中初始化数组时,它会在内存中的其他地方创建一个新数组,并且引用指向它。

如果是多维数组 ([,]),情况就大不相同了。当您初始化这样的数组时,会创建一个内存块,它的大小等于数组所有维度的乘积。从技术上讲,大小为 [M,N] 的多维数组在内存中的表示方式与大小为 [M * N] 的简单数组相同。多个索引的访问基本上只是一个语法糖,框架通过维度的乘积计算元素的实际位置。

如果您要分配非常大的多维数组,C# 需要找到连续的内存而不是交错的数组。我们有一个场景,我们分配了过多的这些大型数组(1500*1500 = 250 万个双精度数组)并且 c# 会定期冻结 20-50 秒 以进行垃圾收集。