18

I wanted to try to allocate a 4 billion bytes array and this is my C# code:

long size = 4 * 1000;
size *= 1000;
size *= 1000;
byte[] array = new byte[size];

this code fails with System.OverflowException on the line containing new. Okay, turns out Length returns int, so the array length is also limited to what int can store.

Then why is there no compile-time error and long is allowed to be used as the number of array elements at allocation?

4

5 回答 5

21

Because the specification says so in section 7.6.10.4:

Each expression in the expression list must be of type int, uint, long, or ulong, or implicitly convertible to one or more of these types.

This is most likely to easily allow creation of arrays larger than 2 GiB, even though they are not supported yet (but will be without a language change once the CLR makes such a change). Mono does support this, however and .NET 4.5 apparently will allow larger arrays too.

Regarding array length being an int by the way: There is also LongLength, returning a long. This was in .NET 1.1 and probably a future-proofing change.

于 2012-06-08T08:35:38.613 回答
10

why long is allowed as array length?

Answer is: long in .net means Int64

And array indexing can be Int64 according to specification.

2nd question: Why overflowexception is showing?

Because any single object can not be allocated more than 2GB of memory.

于 2012-06-08T08:45:40.540 回答
7

It is a limitation of the CLR, no single object can exceed 2GB, including arrays:

Large array C# OutOfMemoryException

This is regardless of 32-bit or 64-bit OSs. That said, it doesn't stop you from using more than that amount in total, just not on one object.

It is a runtime error because if you keep the long (or other initializing value) within range, it will work.

You can initialize arrays with all integral types: sbyte, char, short, int, and long - all compile; the unsigned variants work too.

于 2012-06-08T08:35:46.160 回答
4

There is a solution in .Net 4.5-4.6 for allowing large size for an array.

<runtime>
    <gcAllowVeryLargeObjects enabled="true" />
</runtime>

See documentation.

于 2016-01-14T00:36:48.037 回答
3

The long is an integral type, so it can be used to define the array; the exception is from building too large of an array, not specifically from using a long.

Ex, this works just fine:

long size = 20;
byte[] array = new byte[size];
于 2012-06-08T08:37:48.257 回答