0

This is a purelly theoretical question, so please do not warn me of that in your answers.

If I am not mistaken, and since every array in .NET is indexed by an Int32, meaning the index ranges from 0 to Int32.MaxValue.

Supposing no memory/GC constraints are involved an array in .NET can have up to 2147483648 (and not 2147483647) elements. Right?

bjb568
  • 11,089
  • 11
  • 50
  • 71
Miguel
  • 3,466
  • 8
  • 38
  • 67
  • Similar/Dupey question : http://stackoverflow.com/questions/1391672/what-is-the-maximum-size-that-an-array-can-hold – gideon Mar 20 '11 at 07:53
  • if you find you need an array with more than 2147483647 items, you should probably look for another algorithm... – Mitch Wheat Mar 20 '11 at 07:54

1 Answers1

9

Well, in theory that's true. In fact, in theory there could be support for larger arrays - see this Array.CreateInstance signature which takes long values for the lengths. You wouldn't be able to index such an array using the C# indexers, but you could use GetValue(long).

However, in practical terms, I don't believe any implementation supports such huge arrays. The CLR has a per-object limit a bit short of 2GB, so even a byte array can't actually have 2147483648 elements. A bit of experimentation shows that on my box, the largest array you can create is new byte[2147483591]. (That's on the 64 bit .NET CLR; the version of Mono I've got installed chokes on that.)

EDIT: Just looking at the CLI spec, it specifies that arrays have a lower bound and upper bound of an Int32. That would mean upper bounds over Int32.MaxValue are prohibited even though they can be expressed with the Array.CreateInstance calls. However, it also means it's permissable to have an array with bounds Int32.MinValue...Int.MaxValue, i.e. 4294967296 elements in total.

EDIT: Looking again, ECMA 335 partition III section 4.20 (newarr) specifies that a initializing a vector type with newarr has to take either a native int or int32 value. So it looks like while the normally-more-lenient "array" type in CLI terminology has to have int32 bounds, a "vector" type doesn't.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thank you very much Jon! Of course in practical terms that's not possible, but when code correctness is mandatory one has to deal with this kind of things. – Miguel Mar 20 '11 at 07:54
  • @Miguel: what has "code correctness " got to do with your question? – Mitch Wheat Mar 20 '11 at 07:55
  • I need to assure theoretical limits for these kind of things are never exceeded under any circunstance. – Miguel Mar 20 '11 at 07:56
  • 1
    @Miguel: Surely you need to make sure that the *practical* limits are never exceeded... because they're what will actually determine whether code can run or not. "Correct" code which crashes isn't really useful, is it? What's the context here? Does a limit of `long.MaxValue` help you, if that's the true theoretical constraint rather than `int.MaxValue`? You should read the CLI spec for more details. – Jon Skeet Mar 20 '11 at 08:03
  • Why is the array overhead 56 bytes for a 2GB array on a 64-bit machine? –  Jul 07 '11 at 23:37
  • @0A0D: I wouldn't say it's an *overhead* as such - while there clearly *is* an overhead (24 bytes on x64 as per http://msmvps.com/blogs/jon_skeet/archive/2011/04/05/of-memory-and-strings.aspx) I would say it's more that the limit is slightly less than the theoretical max, that's all. – Jon Skeet Jul 08 '11 at 05:19
  • @Jon: So basically there is a confirmed overhead of 24 bytes but that remaining 32 bytes is just a buffer between the realistic max and theoretical max? This website: http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=659 says that it is clear that the overhead is 56 bytes. –  Jul 08 '11 at 10:49
  • @0A0D: Well, it's confirmed by me... follow my link to see my testing methodology. It looks like the article you're referring to is inferring the overhead *just* from the limit, which is silly IMO. – Jon Skeet Jul 08 '11 at 10:50
  • @JonSkeet - Looking for up to date information on this. Mainly, can I have an array that has over 2^32 elements. Has this changed on any more recent versions of the CLR? – Mike Christensen Apr 08 '14 at 02:04
  • @MikeChristensen: Well, you can now have arrays which are larger than 4GB in size (on a 64-bit CLR, if you set a flag), but according to [the documentation](http://msdn.microsoft.com/en-us/library/hh285054.aspx) there's still a limit of 2^32 elements, and the maximum index in any one dimension is just under half that. – Jon Skeet Apr 08 '14 at 05:45
  • @JonSkeet - Thanks Jon! It seems that [Mono implements Big Arrays](http://www.mono-project.com/Release_Notes_Mono_2.0#Big_Arrays) since 2.0, and they claim this is permitted by ECMA standard. When you refer to the *CLI spec*, I assume you mean this is the specification of how the Microsoft CLR is implemented, but there is nothing in the CLS that would prohibit other runtimes from implementing arrays larger than 2^32 elements. The company I just started working at has a need for *very* large arrays; we're now considering Mono as an option. – Mike Christensen Apr 09 '14 at 01:37
  • @MikeChristensen: No, I suspect I meant ECMA 335. (It was 3 years ago, so I can't be 100% sure...) Partition II, section 14.2 specifies bounds as Int32. Interestingly, partition III, section 4.20 (`newarr`) specifies the number of elements as an "`native int` or `int32`" - which suggests there could be a *vector* with a 64-bit upper bound, but not an *array* (in CLI terminology). Will edit my answer with that. – Jon Skeet Apr 09 '14 at 06:19