Hallo,
ich wollte alten Code umstellen und ein Interface implementieren anstatt überall im Code die Klassenimplementierung zu kennen. Die Umstellung klappte recht gut und alle
Unit Tests laufen erfolgreich durch. Als ich dann aber die Speichercheck Option angeschaltet habe kam es bei einem Testfall zu nicht wieder freigegebenen Speicher. Benutze ich die Klassen entsteht kein Speicherproblem. Die Klasse implementiert "TInterfacedObject" und daher sollte sich ja Delphi um das Aufräumen des Speichers kümmern. Das klappt auch in fast allen Tests.
Der Code ist ein Formelparser der dann die Ableitung bilden kann. Bei "3*r^2" kommt es allerdings zum Speicherleck, da hier die Ableitungsregeln für die Multiplikation und Potenzen angewendet werden.
Für die Ableitung wird eine Formel-Instanz nach den Regeln erstellt.
Multiplikation
Code:
var newOp1:=TMultiplyTerm.create(fop1.getDerivative, fop2.copy);
var newOp2:=TMultiplyTerm.create(fop1.copy, fop2.getDerivative);
var temp:=TAddTerm.create(newop1.simplify, newop2.simplify);
result:=temp.simplify;
{$IFDEF TERM_INTERFACE}
newop1:=nil;
newop2:=nil;
temp:=nil;
{$ELSE}
newop1.Free;
newop2.Free;
temp.Free;
{$ENDIF}
Potenz
Code:
var newop2:=TPowerTerm.create(getFirstOperand.copy, TConstantTerm.create(getSecondOperand.getValue(0)-1));
var temp:=TMultiplyTerm.create(getSecondOperand.copy, newop2.simplify);
result:=temp.simplify;
{$IFDEF TERM_INTERFACE}
newop2:=nil;
temp:=nil;
{$ELSE}
newop2.free;
temp.Free;
{$ENDIF}
Laut meinem Verständnis ist ja das setzen auf NIL von Hand unnötig. Es hat in diesem Testfall auch keinen Effekt.
Simplify, Copy und getDerivative erstellen jeweils eine neue Instanz.
Irgendwie scheint die Referenzählung bei der Komplexität durcheinander zu kommen. Hat jemand evtl. eine Idee?
Ich habe auch ein TestTool erstellt welches bei jedem Create und Destroy eine Logausgabe erstellt.
Vielen Dank im Vorraus
Nick Bierwisch