并非我需要这样做,但我想了解它是如何工作/不工作的。我用谷歌搜索了一个数组的最大长度,并且找不到任何东西。
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());
我想一个跟进的问题是,如果有限制并且我在该限制之外初始化,为什么在使用时只创建时没有例外?这是编译器应该捕获的东西吗?
答案 0 :(得分:5)
数组的基础IL操作码处理IntPtr
(在IL文档中称为 native int ):
newarr
创建一个数组,并接受IntPtr
ldelem
和stelem
读取和写入元素,并使用IntPtr
索引ldlen
返回数组的长度,并返回无符号IntPtr
我预计32位平台上2 ^ 31-1的元素数量会受到理论上的限制,而64位平台上的元素数量则为2 ^ 63-1。
但是,我只是在我的64位PC上尝试了这个代码,并且在第一次分配时得到OutOfMemoryException
,所以显然实际限制较小。
答案 1 :(得分:3)
根据SpankyJ,.NET 2.0至少每个阵列的限制为2 GB。 8个字节(sizeof长)* ~2 ^ 31 = 16千兆字节(更不用说实际需要的内存)。至于溢出,我同意marcc,可能是因为数组预期是int-indexed(参见例如this method虽然我对此有点不确定,因为this overload采用Int64数组长度。这可能是仅在更高版本中可用的扩展名。
总的来说,这主要是一个理论问题。任何真正依赖于此的人都可能做错了。
答案 2 :(得分:0)
数组的索引是int,不长。所以,我猜技术上新的long [int.MaxValue]将是最大的。但是你仍然可以得到你看到的OutOfMemoryException,如果你真的用完了内存。你是在32位操作系统上运行吗?没有设置的最大长度,除了索引值是int,而不是long。