I was curious how long a dynamic array could be so I tried
SetLength(dynArray, High(Int64));
That has a value of 9,223,372,036,854,775,807 and I figure that would be the largest number of indexes I could reference anyway. It gave me a:
ERangeError with message 'Range check error'.
So I tried:
SetLength(dynArray, MaxInt);
and got the same error!
Interestingly I could call it with
SetLength(dynArray, Trunc(Power(2, 32));
Which is actually twice the size of MaxInt!
I tried
SetLength(dynArray, Trunc(Power(2, 63) - 1));
Which is the same as High(Int64), and that failed too.
Short of continued trial and error, does someone know the maximum size? Does it depend on the size of the elements in the array?
I am using Delphi 2009. Will it be different for different versions (obviously when Commadore comes out it should be greater!)
Therefore, the length of the dynamic array size is 5 and its capacity is 10. The dynamic array keeps track of the endpoint.
Although Length is most often used to learn the length of a dynamic array, you can also call Length to find the length of an open array parameter or even a static array. For an array, Length(A) always returns Ord(High(A)) - Ord(Low(A)) + 1 .
Dynamic array usually have a growth factor of 3/2 to 2. But once the memory is allocated, it is never shrank automatically.
The Length function returns either the number of characters in SourceString, or the number of elements in SourceArray. It is often used to loop around all characters in a string or elements in an array. Arrays start at index = 0 by default. So the length of such an array is 1 more than the highest index.
The answer is clear from System.DynArraySetLength procedure, from line 20628:
Inc(neededSize, Sizeof(Longint)*2);
if neededSize < 0 then
Error(reRangeError);
The maximum value you can allocate without raising a range check error is therefore theoretically Maxint - SizeOf(Longint) * 2. Practically, you will get an out-of-memory error depending on how much memory is available.
There's no point in speculating about the maximum theoretical length of a dynamic array, as the maximum practical length is much smaller.
The size of the data structure and the data contained in it has to be smaller than the maximum memory an application can allocate, minus the memory the application code itself, the stack and the other data will need. On Windows (32 bit, the only version we mere mortals can target with Delphi right now) this is a virtual address range of 2 GByte, or 3 GByte with a special switch for the OS loader, for each application. I'm not sure though that a Delphi application can even handle the 3 GByte memory space, as the last third would have negative values for offsets in all places where integers are used instead of LongWords.
So you could try to allocate a dynamic array of say 80% or 90% of MaxInt div SizeOf(array element)
- with the most probable result that the allocation of that memory block fails at runtime.
Also: giving an int64 length and getting no exception would not mean that the array has the intended length. Consider this code:
procedure TForm1.Button1Click(Sender: TObject);
var
a: array of byte;
l: int64;
begin
l := $4000000000;
SetLength(a, l);
Caption := IntToStr(Length(a));
end;
If range checking is off this will compile without hints and warnings, and run without exceptions. It has only the slight problem that the array has length 0 after the call to SetLength(). So for the checks in your question you should definitely read back the length of the dynamic array after a successful SetLength(), it is the only way to be sure that the compiler and runtime did what you intended.
Note that afaik elementcount is also limited, more than 2^31-1 is unlikely. It could be that size has the same limit (to avoid signed<>unsigned issues in the RTL) I doubt that more of than 2GB is possible even in /3GB mode.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With