Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is "long" being allowed as array length in C#?

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?

like image 480
sharptooth Avatar asked Jun 08 '12 08:06

sharptooth


4 Answers

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.

like image 108
Joey Avatar answered Nov 15 '22 19:11

Joey


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.

like image 21
Md Kamruzzaman Sarker Avatar answered Nov 15 '22 18:11

Md Kamruzzaman Sarker


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.

like image 7
Adam Houldsworth Avatar answered Nov 15 '22 18:11

Adam Houldsworth


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

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

See documentation.

like image 4
Ardahan Kisbet Avatar answered Nov 15 '22 18:11

Ardahan Kisbet