In another question, David Heffernan posted a comment about his "all time least favourite Delphi construct":
SetLength(FItems, Length(FItems)+1);
The construct he dislikes was heavily used in the Pebongo project, such as in this excerpt:
procedure TBSONDocument.ReadStream( F: TStream );
var
len : integer;
elmtype : byte;
elmname : string;
begin
Clear;
f.Read( len, sizeof( len ) );
f.Read( elmtype, sizeof( byte ) );
while elmtype <> BSON_EOF do // Loop
begin
elmname := _ReadString( f );
SetLength( FItems, length( FItems ) + 1 ); // This, spotted by TOndrej
case elmtype of
BSON_ARRAY: FItems[high( FItems )] := TBSONArrayItem.Create;
BSON_BINARY: FItems[high( FItems )] := TBSONBinaryItem.Create;
...
end;
f.Read( elmtype, sizeof( byte ) );
end;
end;
What are the alternatives?
This is known as dynamic memory allocation in C programming. To allocate memory dynamically, library functions are malloc() , calloc() , realloc() and free() are used. These functions are defined in the <stdlib. h> header file.
To allocate memory for an array, just multiply the size of each array element by the array dimension. For example: pw = malloc(10 * sizeof(widget)); assigns pw the address of the first widget in storage allocated for an array of 10 widget s.
Because the data is added and removed in a last-in-first-out manner, stack-based memory allocation is very simple and typically much faster than heap-based memory allocation (also known as dynamic memory allocation) e.g. C's malloc .
Space is allocated by calling malloc with the number of bytes needed (for strings this is always one more than the maximum length of the string to be stored): char *pc = malloc(MAXSTR + 1) ; // can hold a string of up to MAXSTR characters.
It's not the SetLength()
itself that is bad but incrementing the length in the loop. Example of bad code:
SetLength( Result.FItems, 0 );
for i := 0 to high( FItems ) do
begin
SetLength(Result.FItems, Length(Result.Fitems)+1);
Result.FItems[i] := FItems[i].Clone;
end;
In this case array is rearranged and reallocating memory on each iteration. Your posted example doesn't show bad usage of SetLength()
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