Not that I would ever need to do this, but I want to understand how it works/doesn't work. I googled quite a bit for the maximum length of an array and can't really find anything.
long[] hugeArray = new long[long.MaxValue];
//No exceptions
Console.WriteLine("Init");
//Overflow exception
Console.WriteLine(hugeArray.LongLength.ToString());
hugeArray = new long[int.MaxValue];
//OutOfMemoryException
Console.WriteLine( hugeArray.Length.ToString());
And I guess a follow up question would be, if there is a limit and I am initializing outside that limit, why no exception when creating only when using? And is this something the compiler should catch?
According to SpankyJ, .NET 2.0 at least had a limit of 2 GB per array. 8 bytes (sizeof long) * ~2^31 = 16 gigabytes (not to mention the actual memory required). As for the Overflow, I agree with marcc that is probably because arrays are expected to be int-indexed (see e.g. this method Though I'm a bit uncertain regarding this, as this overload takes an array of Int64 lengths. This may be an extension only available in later versions.
Overall, though, this is mostly a theoretical issue. Anyone actually relying on this is likely doing something wrong.
The underlying IL opcodes for arrays deal with IntPtr
(known as native int in the IL documentation):
newarr
creates an array, and accepts an IntPtr
ldelem
and stelem
read and write elements, and they use an IntPtr
index
ldlen
returns the length of an array, and it returns an unsigned IntPtr
I'd expect a theoretical limit on the number of elements of 2^31-1 on 32-bit platforms, and 2^63-1 on 64-bit platforms.
However, I just tried this code on my 64-bit PC, and I got an OutOfMemoryException
on the first allocation, so clearly the practical limits are smaller.
The index of an array is an int, not long. So, I guess technically new long[int.MaxValue] would be the maximum. But you could still get the OutOfMemoryException you are seeing if you really do run out of memory. Are you running this on a 32-bit OS? There isn't a set maximum length, other than the index value is an int, not a long.