分配大型阵列; OutOfMemoryException VS OverflowException

时间:2012-06-08 09:45:16

标签: c# .net

请考虑以下事项:

long size = int.MaxValue;
long[] huge = new long[size];     // throws OutOfMemoryException
long[] huge = new long[size + 1]; // throws OverflowException

我知道单个对象的大小有2GB限制,这解释了第一个异常,但是为什么一旦元素数量超过32位,我会得到一个不同的异常?

(如果这很重要,我正在使用64位计算机。)

编辑:我还可以定义并使用一个接受long而没有问题的索引器:

internal sealed class MyClass
{
   public object this[long x]
   { 
      get
      {
         Console.WriteLine("{0}", x);
         return null;
      }
   }
}

...

long size = int.MaxValue;
MyClass asdf = new MyClass();
object o = asdf[size * 50]; // outputs 107374182350

2 个答案:

答案 0 :(得分:8)

C#数组由System.Int32编制索引。由于size + 1超出Int32.MaxValue,因此会出现整数溢出。

如果您真的想使用Array.CreateInstance作为索引,请使用需要很长时间的long重载。

答案 1 :(得分:2)

所以从我收集的内容来看,这里发生了类似的事情:

  • 索引器通常可以使用任何类型的参数。
  • 内置数组索引器可以接受任何整数类型...
  • 但是内置数组索引器的底层实现需要一个<= Int32.MaxValue的值,并且会为超过Int32.MaxValue的值抛出溢出异常。

虽然后一点感觉像是某种奇怪的矛盾(接受大于Int32的类型,但如果碰巧实际使用任何这些额外的位,则抛出异常),这显然是副作用事实上,其中一些是为了将来允许具有超过Int32.MaxValue元素的数组实现的半实现。