Mit nur FillChar
falsch ist hier. Wenn eines der WideString
Mitglieder nicht leer ist, werden Sie diese auf diese Weise verlassen. Stattdessen schlage ich folgendes:
Finalize(IPInfo);
FillChar(IPInfo, SizeOf(TIPInfo), 0);
Oder eine andere Art und Weise ist ein Standardsatz als definieren typisierten Konstante:
const
DefaultIPInfo: TIPInfo =();
Dann können Sie einfache Zuordnung verwenden:
IPInfo := DefaultIPInfo;
In der modernen Versionen von Delphi können Sie stattdessen diesen viele lesbaren Code verwenden:
IPInfo := Default(TIPInfo);
Weitere Informationen zu diesem speziellen Thema finden Sie in folgenden Themen:
Beachten Sie, dass das Leck in Ihrem Code ist schwer zu finden, weil WideString
Variablen als COM BSTR
Objekte implementiert werden, und auf dem COM-Heap zugewiesen. Wenn Sie Speicherleckerkennung für den Delphi-Speicher-Manager verwenden, wird das Leck daher nicht erkannt, da es von einem anderen Heap ausgelaufen ist.
Da Ihr Datensatz ein verwalteter Typ ist und nur verwaltete Typen enthält, könnten Sie in diesem Fall einen out
-Parameter mit gutem Ergebnis verwenden. Für verwaltete Typen, bedeuten out
Parameter, dass der Compiler Code, an der Aufrufstelle generieren, auf Standardeintrag initialisieren, bevor es im Vorbeigehen
Betrachten Sie das folgende Programm:.
{$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.
Die Ausgabe lautet:
Wenn Ihr Datensatz eine Mischung aus verwalteten und nicht verwalteten Typen enthält, ist die Situation nicht so gut.
{$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.
Die Ausgabe lautet:
Foo
42
42
Nur die verwalteten Mitglieder Standard für out
Parameter initialisiert sind. Sie sollten also die Variable selbst initialisieren, auch wenn sie als out
Parameter übergeben wird.
Mehr zu out
Parameter finden Sie hier: What's the difference between "var" and "out" parameters?
ich ein out-Parameter verwenden würde, wenn die Funktion nicht den Parameter liest. Auch in diesem Fall ist es klar, dass die Funktion selbst es initialisieren sollte und nicht der Aufrufer. FillChar initialisiert verwaltete Typen wie Strings nicht in jeder Situation (obwohl dies in Ihrem Fall der Fall ist), also initialisiere ich jedes Feld einzeln. –
In diesem Fall sind alle Datensatzfelder "WideString", das vom Compiler automatisch initialisiert wird, so dass die Funktion überhaupt nichts initialisieren muss. Davon abgesehen stimme ich R. Beiboer zu, die Verwendung von "out" statt "var" ist die beste Wahl. –
@RemyLebeau Die Mitglieder könnten willkürliche Werte von einer früheren Verwendung dieses Objekts haben. Sie müssen also zugewiesen werden. –