Нужно ли завершать массив записей в Delphi?

В моем приложении у меня есть следующие записи:

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

и я использую эту запись в этот массив:

Transactions = array of TTransaction;

Я сохраняю массив загруженным во время выполнения, но в данный момент мне нужно очистить все данные и добавить новые.

достаточно просто использовать:

SetLength(Transactions, 0); ?

или мне нужно что-то доработать ?

3 ответов


есть три способа освободить память, связанную с динамическим массивом,a:

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

Это зависит от вас, какой из них использовать.

на документация говорит то же самое, хотя и в несколько кругом мода:

чтобы освободить динамический массив, назначьте nil переменной, которая ссылается на массив, или передайте переменную для завершения; любой из этих методов избавляется от массива, если нет других ссылок к нему. Динамические массивы автоматически освобождаются, когда их количество ссылок падает до нуля. Динамические массивы длины 0 имеют значение nil.

это освободит всю память, связанную с массивом, включая любые вложенные управляемые типы, такие как строки, динамические arrys и т. д. которые принадлежат вашему типу записи.

Если вам нужно изменить размер массива для будущего использования и иметь новые данные, просто измените размер с помощью SetLength и инициализировать остальные элементы соответственно.


установка длины массива на ноль уничтожит массив, что идет вразрез с вашим желанием "сохранить массив загруженным.- Однако это...!--6-->будет освободите память для всех записей и их строк (для любых строк, количество ссылок которых равно 1 в то время).

если вы просто хотите освободить память для строк, но сохранить выделенную память записи (потому что вы планируете выделить другой набор записей сразу после этого, и вы не хотите тратить время на освобождение и перераспределение той же памяти), то вы можете очистить только члены строки, но нет ни одного вызова библиотеки, чтобы сделать это за вас. Вместо этого вам нужно будет написать цикл и очистить поля каждой записи самостоятельно.

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

если в записи есть много полей, которые нуждаются в очистке, то было бы удобнее назначить значение по умолчанию TTransaction значение для каждого элемента массива. Вы можете использовать Default функция, или в более старых версиях Delphi вы можете объявить TTransaction что все его поля уже очищены:

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

for i := 0 to High(transactions) do
  transactions[i] := ClearTransaction;
  // or
  transactions[i] := Default(TTransaction);

SetLength (transactions,0) не очень хорошая идея. Я думаю, что лучший способ-это повторно инициализировать всех участников записи. Таким образом, вы сохраняете переменную загруженной.

можно использовать SetLength (transactions,0) Если вам больше не нужна переменная, Используйте как можно меньше памяти. Конечно, если он вам снова понадобится где-то в программе, вы можете изменить его длину, предположим, вы его знаете.

вам не нужно ничего дорабатывать, потому, что это запись, а не класс. Записи не имеют конструкторы или деструкторы, как классы.