@stahli *hüstel*
Es gibt da so eine Besonderheit mit den Interfaces und der direkten Argumentsübergabe. Das ist auch ein Grund, warum es bei den ganzen Comparer-Erzeugern eine
class function Construct
gibt und der normale
constructor Create
versteckt ist.
Nehmen wir mal das Eingangs-Beispiel
Delphi-Quellcode:
var
TCo: TPositionComparer;
LPC : IComparer<TPosition>
begin
FPositions.Add(Result);
TCo := TPositionComparer.Create;
// ACHTUNG! TCo ist keine Interface-Variable,
// wird aber jetzt als Interface übergeben (Sort Argument)
// und nach dem Sort ist die Instanz durch die Referenz-Zählung
// zerstört. In TCo finden wir nur noch einen nutzlosen Referenz-Zeiger
FPositions.Sort( TCo );
FPositions.Sort( TCo ); // hier rummst es jetzt
// besser so:
LPC := TPositionComparer.Create;
FPositions.Sort( LPC );
FPositions.Sort( LPC ); // alles ok, denn LPC ist eine Interface-Variable
// jetzt das Beste zum Schluss
FPositions.Sort( TPositionComparer.Create );
FPositions.Sort( TPositionComparer.Create ); // alles ok, alles funktioniert
// wirklich alles? NEIN, wir haben ein Speicherleck produziert
end;
Bei der direkten Argumentsübergabe der Referenz, wird der Referenz-Zähler
nicht erhöht, darum auch nicht verringert, dadurch wird kein
_AddRef
und kein
_Release
aufgerufen, und dadurch wird die Instanz nicht freigegeben.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ea 0a 4c 14 0d b6 3a a4 c1 c5 b9
dc 90 9d f0 e9 de 13 da 60)