Search code examples
c#arraysmultidimensional-array.net-4.5gcallowverylargeobjects

Array.Copy --> Arrays larger than 2GB are not supported


I'm using the Array.Copy Method (Array, Array, Int64). I've the following static method

public static T[,] Copy<T>(T[,] a)
    where T : new()
{
    long n1 = a.GetLongLength(0);
    long n2 = a.GetLongLength(1);
    T[,] b = new T[n1, n2];
    System.Array.Copy(a, b, n1 * n2);
    return b;
}

and the following code to test it

double[,] m1 = new double[46340, 46340];
double[,] m2 = Copy(m1); // works

double[,] m3 = new double[46341, 46341];
double[,] m4 = Copy(m3); // Arrays larger than 2GB are not supported
                         // length argument of Array.Copy

I'm aware of <gcAllowVeryLargeObjects enabled="true" /> and I've set it to true.

I saw in the documentation of Array.Copy Method (Array, Array, Int64) that there is the following remark for the length argument.

A 64-bit integer that represents the number of elements to copy. The integer must be between zero and Int32.MaxValue, inclusive.

I cannot understand why there is this limit for the length argument when the type is Int64? Is there a workaround? Is it planned to remove this limit in an upcoming version of .net?


Solution

  • A workaround could be the following code

    public static T[,] Copy<T>(T[,] a)
        where T : new()
    {
        long n1 = a.GetLongLength(0);
        long n2 = a.GetLongLength(1);
        long offset = 0;
        long length = n1 * n2;
        long maxlength = Int32.MaxValue;
        T[,] b = new T[n1, n2];
        while (length > maxlength)
        {
            System.Array.Copy(a, offset, b, offset, maxlength);
            offset += maxlength;
            length -= maxlength;
        }
        System.Array.Copy(a, offset, b, offset, length);
        return b;
    }
    

    where the array is copied in blocks of the size Int32.MaxValue.