Нужно ли мне дорабатывать массив записей в Delphi? - программирование
Подтвердить что ты не робот

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

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

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

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

Transactions = array of TTransaction;

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

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

SetLength(Transactions, 0); ?

Или мне нужно что-то финализировать?

4b9b3361

Ответ 1

Существует три способа освобождения памяти от связей с динамическим массивом, a:

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

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

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

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

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

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

Ответ 2

Установка длины массива в ноль приведет к уничтожению массива, что противоречит вашему желанию "сохранить массив загруженным". Тем не менее, он освободит память для всех записей и их строк (для любых строк, счетчик ссылок которых равен 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);

Ответ 3

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

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

Вам не нужно ничего финализировать, потому что это запись, а не класс. В записях нет конструкторов или деструкторов, например классов.