Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need to finalize array of records in Delphi?

In my application I have the following record:

TTransaction = record
  Alias: string
  Description: string
  Creation: TDateTime
  Count: Integer
end;

and I'm using this record in this array:

Transactions = array of TTransaction;

I'm keeping the array loaded during runtime, but at a given time I need to clear all data and add some new.

Is it enough just to use:

SetLength(Transactions, 0); ?

Or do I need to finalize something ?

like image 672
EProgrammerNotFound Avatar asked Feb 19 '13 13:02

EProgrammerNotFound


People also ask

What is an array in delphi?

Arrays allow us to refer to a series of variables by the same name and to use a number (an index) to call out individual elements in that series. Arrays have both upper and lower bounds and the elements of the array are contiguous within those bounds.

How do I free a record in Delphi?

Assuming you have a Delphi version that supports implementing methods on a record, you could clear a record like this: type TSomeRecord = record field1: integer; field2: string; field3: boolean; procedure Clear; end; procedure TSomeRecord.


2 Answers

There are three ways to deallocate the memory associates with a dynamic array, a:

SetLength(a, 0);
Finalize(a);
a := nil;

It's up to you which one to use.

The documentation says the same, albeit in a slightly round about fashion:

To deallocate a dynamic array, assign nil to a variable that references the array or pass the variable to Finalize; either of these methods disposes of the array, provided there are no other references to it. Dynamic arrays are automatically released when their reference-count drops to zero. Dynamic arrays of length 0 have the value nil.

This will release all memory associated with the array, including any nested managed types, such as strings, dynamic arrys etc. that are owned by your record type.

If you need to resize the array for future use, and have the new data available, simply resize using SetLength, and initialise the remaining elements appropriately.

like image 195
David Heffernan Avatar answered Sep 21 '22 12:09

David Heffernan


Setting the array length to zero will destroy the array, which goes counter to your desire to "keep the array loaded." However, it will free the memory for all the records and their strings (for any strings whose reference count is 1 at the time).

If you just want to free the memory for the strings, but keep the record memory allocated (because you plan to allocate another set of records immediately afterward, and you don't want the waste of releasing and re-allocating the same memory), then you can clear just the string members, but there's no single library call to do it for you. Instead, you'll need to write a loop and clear each record's fields yourself.

for i := 0 to High(transactions) do begin
  transactions[i].alias := '';
  transactions[i].description := '';
end;

If there are lots of fields in the record that need clearing, then it might be more convenient to assign a default TTransaction value to each element of the array. You can use the Default function, or in older versions of Delphi you can declare a TTransaction that has all its fields clear already:

const
  ClearTransaction: TTransaction = (alias: ''; description: ''; creation: 0; count: 0);

for i := 0 to High(transactions) do
  transactions[i] := ClearTransaction;
  // or
  transactions[i] := Default(TTransaction);
like image 29
Rob Kennedy Avatar answered Sep 21 '22 12:09

Rob Kennedy