Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Max length for a dynamic array in Delphi?

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!)

like image 317
Jim McKeeth Avatar asked Jun 12 '09 04:06

Jim McKeeth


People also ask

What is the size of dynamic array?

Therefore, the length of the dynamic array size is 5 and its capacity is 10. The dynamic array keeps track of the endpoint.

How do you find the length of an array in Delphi?

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 .

Do dynamic arrays shrink?

Dynamic array usually have a growth factor of 3/2 to 2. But once the memory is allocated, it is never shrank automatically.

How do you use length in Delphi?

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.


3 Answers

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.

like image 160
Ondrej Kelle Avatar answered Oct 27 '22 19:10

Ondrej Kelle


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.

like image 28
mghie Avatar answered Oct 27 '22 18:10

mghie


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.

like image 45
Marco van de Voort Avatar answered Oct 27 '22 17:10

Marco van de Voort