代码之家  ›  专栏  ›  技术社区  ›  Jim McKeeth

Delphi中动态数组的最大长度?

  •  4
  • Jim McKeeth  · 技术社区  · 15 年前

    我很好奇动态数组可以有多长时间,所以我尝试了

    SetLength(dynArray, High(Int64));
    

    它的值为9223372036854775807,我认为这将是我所能引用的最大数量的索引。它给了我一个:

    带消息“范围检查错误”的ErangeError。

    所以我尝试:

    SetLength(dynArray, MaxInt); 
    

    得到同样的错误!

    有趣的是,我可以称之为

    SetLength(dynArray, Trunc(Power(2, 32));
    

    实际上是Maxint的两倍大!

    我试过

    SetLength(dynArray, Trunc(Power(2, 63) - 1));
    

    与high(int64)相同,也失败了。

    除了不断的试验和错误,有人知道最大尺寸吗?它是否取决于数组中元素的大小?

    我使用的是Delphi2009。不同版本会有不同吗(很明显,当Commadore出现时,它应该更大!)

    4 回复  |  直到 10 年前
        1
  •  17
  •   Ondrej Kelle    15 年前

    从System.DynarraySetlength过程,从第20628行可以清楚地找到答案:

    Inc(neededSize, Sizeof(Longint)*2);
    if neededSize < 0 then
      Error(reRangeError);
    

    因此,在不引起范围检查错误的情况下,可以分配的最大值在理论上是maxint-sizeof(longint)*2。实际上,根据可用内存的多少,您将得到一个内存不足错误。

        2
  •  4
  •   mghie    15 年前

    由于最大实际长度要小得多,因此没有必要推测动态阵列的最大理论长度。

    数据结构的大小及其包含的数据必须小于应用程序可以分配的最大内存,减去应用程序代码本身、堆栈和其他数据需要的内存。在Windows上(32位,我们人类目前唯一能用Delphi瞄准的版本),这是一个2 GB的虚拟地址范围,或3 GB的虚拟地址范围,每个应用程序都有一个专用的OS加载程序开关。虽然Delphi应用程序甚至可以处理3G字节的内存空间,但我不确定,因为在所有使用整数而不是长字的地方,最后三分之一的内存空间的偏移量都是负值。

    所以您可以尝试分配一个动态数组,比如80%或90%的 MaxInt div SizeOf(array element) -最可能的结果是在运行时内存块的分配失败。

    另外:给出一个Int64长度并且没有异常并不意味着数组具有预期的长度。考虑此代码:

    procedure TForm1.Button1Click(Sender: TObject);
    var
      a: array of byte;
      l: int64;
    begin
      l := $4000000000;
      SetLength(a, l);
      Caption := IntToStr(Length(a));
    end;
    

    如果关闭范围检查,则编译时将不带提示和警告,并且运行时不带异常。调用后数组的长度为0,这只是一个小问题。 设置长度() . 因此,对于问题中的检查,您一定要在成功后读取动态数组的长度。 设置长度() ,这是确保编译器和运行时按您的预期执行的唯一方法。

        3
  •  1
  •   Marco van de Voort    15 年前

    请注意,afaik元素计数也有限,不太可能超过2^31-1。可能是大小有相同的限制(为了避免RTL中的签名<gt;未签名问题),我怀疑即使在/3GB模式下也可能超过2GB。

        4
  •  1
  •   neue    11 年前

    MMaths:

    最大数组字节大小=2^31-9

    max_array_elements_number=[(2^31-9)/array_element_bytesize]

    代码:

    max_array_elements_number := (MaxInt-Sizeof(Longint)*2) div SizeOf(array_element);
    

    例子:

    type
      TFoo = <type_description>;
      TFooDynArray = array of TFoo
    const
      cMaxMemBuffSize = MaxInt-Sizeof(Longint)*2;
    var
      A : TFooDynArray;
      B : array of int64;
      MaxElems_A : integer;
      MaxElems_B : integer;
    begin
      MaxElems_A := cMaxMemBuffSize div SizeOf(TFoo);
      MaxElems_B := cMaxMemBuffSize div SizeOf(int64);
    
      ShowMessage('Max elements number for array:'#13#10+
                  '1) A is '+IntToStr(MaxElems_A)+#13#10+
                  '2) B is '+IntToStr(MaxElems_B)
                  );
    end;