Использование только FillChar
здесь неправильное. Если какой-либо из членов WideString
не пуст, вы пронесете их таким образом. Вместо этого я предлагаю следующее:
Finalize(IPInfo);
FillChar(IPInfo, SizeOf(TIPInfo), 0);
Или другой способ, чтобы определить запись по умолчанию, как типизированный константа:
const
DefaultIPInfo: TIPInfo =();
Затем вы можете использовать простое задание:
IPInfo := DefaultIPInfo;
В современной версии Delphi вы можете использовать этот гораздо более читаемый код:
IPInfo := Default(TIPInfo);
Более подробно об этой конкретной теме, обратитесь к следующим темам:
Обратите внимание, что утечка в вашем коде трудно найти, потому что WideString
переменные реализованы в виде COM BSTR
объектов, и выделяется на COM куче. Поэтому, если вы используете обнаружение утечки памяти для менеджера памяти Delphi, утечка не будет обнаружена, потому что она просочилась из другой кучи.
В вашем случае, поскольку ваша запись является управляемым типом и содержит только управляемые типы, вы можете использовать параметр out
для хорошего эффекта. Для управляемых типов, out
параметры означают, что компилятор будет генерировать код, на месте вызова, по умолчанию инициализировать запись перед передачей его в
Рассмотрим следующую программу:.
{$APPTYPE CONSOLE}
type
TRec = record
Value: WideString;
end;
procedure Foo1(var rec: TRec);
begin
end;
procedure Foo2(out rec: TRec);
begin
end;
procedure Main;
var
rec: TRec;
begin
rec.Value := 'Foo';
Foo1(rec);
Writeln(rec.Value);
Foo2(rec);
Writeln(rec.Value);
end;
begin
Main;
end.
Выход:
Foo
Если ваша запись содержит сочетание управляемых и неуправляемых типов, то ситуация не так хороша.
{$APPTYPE CONSOLE}
type
TRec = record
Value1: WideString;
Value2: Integer;
end;
procedure Foo1(var rec: TRec);
begin
end;
procedure Foo2(out rec: TRec);
begin
end;
procedure Main;
var
rec: TRec;
begin
rec.Value1 := 'Foo';
rec.Value2 := 42;
Foo1(rec);
Writeln(rec.Value1);
Writeln(rec.Value2);
Foo2(rec);
Writeln(rec.Value1);
Writeln(rec.Value2);
end;
begin
Main;
end.
Выход:
Foo
42
42
только управляемые члены по умолчанию инициализируется для out
параметров. Поэтому ваш лучший выбор - это инициализировать переменную самостоятельно, даже если она передается как параметр out
.
Подробнее о out
параметрах можно найти здесь: What's the difference between "var" and "out" parameters?
Я хотел бы использовать выходной параметр, если функция не читает параметр. Кроме того, в этом случае ясно, что сама функция должна инициализировать его, а не вызывающего. FillChar неправильно инициализирует управляемые типы, такие как строки в каждой ситуации (хотя это и есть в вашем случае), поэтому я бы просто инициализировал каждое поле отдельно. –
В этом случае все поля записи являются «WideString», которые автоматически инициализируются компилятором, поэтому функции вообще не нужно ничего инициализировать. Это, как говорится, я согласен с Р.Бейбором, использование 'out' вместо' var' - лучший выбор. –
@RemyLebeau Члены могут иметь произвольные значения от предыдущего использования этого объекта. Поэтому их нужно назначить. –