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

Jim*_*eth 5 delphi delphi-2009

我很好奇动态阵列有多长,所以我试过了

SetLength(dynArray, High(Int64));
Run Code Online (Sandbox Code Playgroud)

它的值为9,223,372,036,854,775,807,我认为这是我可以参考的最大索引数.它给了我一个:

带有消息'范围检查错误'的ERangeError.

所以我尝试过:

SetLength(dynArray, MaxInt); 
Run Code Online (Sandbox Code Playgroud)

并得到了同样的错误!

有趣的是我可以称之为

SetLength(dynArray, Trunc(Power(2, 32));
Run Code Online (Sandbox Code Playgroud)

这实际上是MaxInt大小的两倍!

我试过了

SetLength(dynArray, Trunc(Power(2, 63) - 1));
Run Code Online (Sandbox Code Playgroud)

这与High(Int64)相同,但也失败了.

没有继续尝试和错误,有人知道最大尺寸?它取决于数组中元素的大小吗?

我正在使用Delphi 2009.对于不同的版本会有所不同(显然当Commadore出来时它应该更大!)

Ond*_*lle 18

从第20628行的System.DynArraySetLength过程可以清楚地看出答案:

Inc(neededSize, Sizeof(Longint)*2);
if neededSize < 0 then
  Error(reRangeError);
Run Code Online (Sandbox Code Playgroud)

因此,理论上Maxint - SizeOf(Longint)*2可以分配的最大值而不会引发范围检查错误.实际上,根据可用的内存量,您将获得内存不足错误.

  • RTL为两个LongInts保留空间,以保存长度和引用计数. (3认同)

mgh*_*hie 5

关于动态阵列的最大理论长度的推测是没有意义的,因为最大实际长度要小得多.

数据结构的大小及其中包含的数据必须小于应用程序可以分配的最大内存,减去应用程序代码本身,堆栈和其他数据所需的内存.在Windows上(32位,我们现在唯一可以用Delphi定位的版本)这是一个2 GByte或3 GByte的虚拟地址范围,每个应用程序都有一个用于OS加载程序的特殊开关.我不确定Delphi应用程序是否可以处理3 GB内存空间,因为在使用整数而不是LongWords的所有地方,最后三分之一的偏移值都会有负值.

因此,您可以尝试分配一个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;
Run Code Online (Sandbox Code Playgroud)

如果范围检查已关闭,则将在没有提示和警告的情况下编译,并且无异常地运行.在调用SetLength()之后,只有一个小问题是数组的长度为0 .因此,对于您的问题中的检查,您应该在成功的SetLength()之后回读动态数组的长度,这是确保编译器和运行时完成您的预期的唯一方法.