Нужно ли завершать массив записей в 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 переменную, которая ссылается на массив, или передайте переменную Finalize; любой из этих методов избавляется от массива, если на него нет других ссылок. Динамические массивы автоматически освобождаются, когда их счетчик ссылок падает до нуля. Динамические массивы длины 0 имеют значение nil.
Это освободит всю память, связанную с массивом, включая любые вложенные управляемые типы, такие как строки, динамические массивы и т. Д., Которые принадлежат вашему типу записи.
Если вам нужно изменить размер массива для использования в будущем и получить новые данные, просто измените размер, используя SetLength
и инициализировать оставшиеся элементы соответствующим образом.
Установка длины массива в ноль уничтожит массив, что идет вразрез с вашим желанием "сохранить массив загруженным". Тем не менее, это освободит память для всех записей и их строк (для любых строк, чей счетчик ссылок равен 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)
если вам больше не нужна переменная, используйте как можно меньше памяти. Конечно, если вам это понадобится снова где-то в программе, вы можете перенастроить его длину, если вы это знаете.
Вам не нужно ничего дорабатывать, потому что это запись, а не класс. Записи не имеют конструкторов или деструкторов, таких как классы.