Memoryleaks

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
FrankS
Beiträge: 13
Registriert: Mi 26. Jan 2022, 18:55

Memoryleaks

Beitrag von FrankS »

Hallo ich wieder,
ich habe jetzt die Umsetzung eines C# Programms (Textadventure-Framework) nach FPC fertig und es läuft soweit. Allerdings habe ich große Probleme mit dem verhindern von memoryleaks beim beenden des Programms. Ich verstehe nicht so recht wie diese zustande kommen. :oops:
Jetzt zu meiner unverschämten Bitte: Vielleicht kann sich mal jemand mein Programm anschauen und mir hilfreiche Hinweise geben.
Zum testen einfach das Programm starten und test eingeben, damit wird eine Komandotestliste abgearbeitet.

Im Anhang mein Projekt inklusive dem C#-Projekt.

Gruß
Frank
Dateianhänge
PascalBiff.zip
(74.67 KiB) 13-mal heruntergeladen

Benutzeravatar
Zvoni
Beiträge: 523
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz/FPC fixes)
CPU-Target: 64Bit
Wohnort: BW

Re: Memoryleaks

Beitrag von Zvoni »

Bin jetzt nicht durch alles durch, aber mir sind sofort zwei Dinge in GameDataUnit aufgefallen.

1) Ich war der Meinung, dass man einen Destructor "overriden" soll. hab jetzt schon die erste Stelle gefunden, wo das Schlüsselwort "override" in der Klassen-Definition fehlt
2) Du rufst FIrgendwas.Destroy auf --> Soll man nicht machen. Benutze FIrgendwas.Free

EDIT: AUTSCH!!!!
gerade gesehen in "class procedure TGameData.InitFObs();"

Code: Alles auswählen

var
    aStringList: TStringList;
begin
    FObs := TObsList.Create;

    FObs.Add(OB_Acorn,     TThing.Create('acorn', 'ordinary-looking acorn'));
    FObs.Add(OB_Bed,       TThing.Create('bed', 'nasty, rather damp bed', false, true));
    FObs.Add(OB_Bin,       TContainerThing.Create('bin', 'smelly old bin', Mass_MEDIUM, true, true, true, true));
        aStringList := TStringList.Create(); aStringList.CommaText := 'smelly,old';
        FObs.KeyData[OB_Bin].Adjectives := aStringList;
    FObs.Add(OB_Bone,      TThing.Create('bone', 'bone that looks as though it has been gnawed by a dog'));
    FObs.Add(OB_BrassKey,  TThing.Create('key', 'small brass key'));
        aStringList := TStringList.Create(); aStringList.CommaText := 'small,brass';
        FObs.KeyData[OB_BrassKey].Adjectives := aStringList;
//        ......
aStringList wird created, einer Eigenschaft zugewiesen, dann NOCHMAL created (und das kommt noch mehrmals vor)?!?!?!?
Zumal die Eigenschaft "Adjectives" ja anscheinend ein TStringList/TStrings ist. Wieso nicht direkt diese Eigenschaft createn?

Desweiteren Createst du TThing innerhalb der Add-Funktion. Dir ist klar, dass du dann keinerlei Referenz mehr darauf hast???
Zumal anscheinend FObs keinen Parent bekommt.

Alles gesagt: Diesen Code würde ich nichtmal mit der Beisszange anfassen
Zuletzt geändert von Zvoni am Fr 30. Jan 2026, 12:25, insgesamt 1-mal geändert.
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Benutzeravatar
Zvoni
Beiträge: 523
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz/FPC fixes)
CPU-Target: 64Bit
Wohnort: BW

Re: Memoryleaks

Beitrag von Zvoni »

Also wenn du dennoch das irgendwie so lassen willst, würde ich wie folgt vorgehen.
Und das ist nur die erste "Änderung".

UNGETESTET.
Bin mir jetzt nicht sicher, ob "Adjectives" automatisch created wird

Code: Alles auswählen

var
    aStringList: TStringList;
begin
    FObs := TObsList.Create;

    aStringList := TStringList.Create(); //<== Einmal createn

    FObs.Add(OB_Acorn,     TThing.Create('acorn', 'ordinary-looking acorn'));
    FObs.Add(OB_Bed,       TThing.Create('bed', 'nasty, rather damp bed', false, true));
    FObs.Add(OB_Bin,       TContainerThing.Create('bin', 'smelly old bin', Mass_MEDIUM, true, true, true, true));

        aStringList.CommaText := 'smelly,old';  //<==
        FObs.KeyData[OB_Bin].Adjectives.AddStrings(aStringList, True);  //<==

    FObs.Add(OB_Bone,      TThing.Create('bone', 'bone that looks as though it has been gnawed by a dog'));
    FObs.Add(OB_BrassKey,  TThing.Create('key', 'small brass key'));

        aStringList.CommaText := 'small,brass';
        FObs.KeyData[OB_BrassKey].Adjectives.AddStrings(aStringList, True);   //<==
//        ......
    aStringList.Free;  //Zum Schluss freigeben
End;    
Anstatt der "aStringList" vielleicht sogar direkt den overload von AddStrings verwenden, und die Strings direkt übergeben
https://www.freepascal.org/docs-html/rt ... rings.html

Code: Alles auswählen

FObs.KeyData[OB_BrassKey].Adjectives.AddStrings(['small','brass'],True);   //<==
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

FrankS
Beiträge: 13
Registriert: Mi 26. Jan 2022, 18:55

Re: Memoryleaks

Beitrag von FrankS »

Hallo Zvoni,
vielen Dank für deine Hinweise.

Ich habe erstmal unbedarft mehr oder weniger die Struktur des C#-Programms übernommen.

Ich dachte und so habe ich es auch getestet (glaube ich wenigstens), daß TFPGMap<TOb,TThing>.Add ein Objekt mit dem Key TOb und einer Kopie der Reference von TThing anlegt.

Mein Problem ist auch, dass ich im erzeugten dump der memoryleaks nicht sehen kann das hier ein Problem vorliegen soll.

Frank

Benutzeravatar
Zvoni
Beiträge: 523
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz/FPC fixes)
CPU-Target: 64Bit
Wohnort: BW

Re: Memoryleaks

Beitrag von Zvoni »

Hallo Frank,

wie gesagt: Das alles war nur der erste Blick in einer Unit.
Es war keine Aussage darüber, dass dies die Ursache für die Speicher-Lecks sind.
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Antworten