Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   IntStringList und Objektfreigabe (https://www.delphipraxis.net/204602-intstringlist-und-objektfreigabe.html)

Shark99 10. Jun 2020 13:21

IntStringList und Objektfreigabe
 
Ich bin dabei eine Klasse von TStringList abzuleiten und zwar eine TIntStrintList, die eine Art Dictionary sein wird.
Delphi-Quellcode:
type

  TIntStringList = class(TStringList)
  public
     function AddInteger(const s: string; i: integer): Integer;
     function GetInteger(const s: string; var i: integer): boolean;
  end;

implementation

function TIntStringList.AddInteger(const s: string; i: integer): Integer;
begin
  if not Sorted then
    Result := Count
  else // sorted
    if Find(S, Result) then // if not found Result is 0
      if Duplicates = dupIgnore then
        Exit;

  InsertItem(Result, S, TObject(i));
end;

function TIntStringList.GetInteger(const s: string; var i: integer): boolean;
begin
  Result := False;
  i := IndexOf(s);
  if i > - 1 then
  begin
      i := Integer(Objects[i]);
      Result := True;
  end;
end;
Ich nutze dabei InsertItem() der StringList, mache aber einen Typecast TObject(i) damit ich direkt einen Integer speichern kann.

Meine Frage ist ob ich die Integers die in Objects[] gespeichert werden vor dem .Free einer Instanz so Liste einzeln manuell freigeben muss, damit kein Speicherleck entsteht?

himitsu 10. Jun 2020 13:27

AW: IntStringList und Objektfreigabe
 
Delphi-Referenz durchsuchenTStringList.OwnsObjects

In den alten NextGen-Compilern (Android/iOS) würde dein Code knallen, da dort Objekte wie Interfaces referenzgezählt sind, aber dein "Objekt" ja Keines ist.

Was ich jetzt genau bezüglich dem "unified memory management" im Windows und NextGen geändert hat, da hatte ich noch keine Zeit mir einen Überblick zu verschaffen ... nicht dass es dort nun auch knallen könnte. :stupid:
https://www.embarcadero.com/products...in-10-4-sydney

TiGü 10. Jun 2020 13:30

AW: IntStringList und Objektfreigabe
 
1. Waaaas? :shock:
2. Warum nimmst du kein richtiges TDictionary, welches seit Delphi 2009 mit dabei ist?
3. Warum willst du einen Integer freigeben? Der Cast auf TObject ist
nur ein Cast, es entsteht keine wirkliche Instanz auf dem Heap. Ergo muss da auch nichts freigeben werden.

Shark99 10. Jun 2020 13:33

AW: IntStringList und Objektfreigabe
 
Danke.

Weil ich ein Delphi 7 Projekt erweitere und es da kein TDictionary gibt.

TurboMagic 10. Jun 2020 20:14

AW: IntStringList und Objektfreigabe
 
Beantwortung der Originalfrage: ja, die müssen freigegeben werden.
Wärst du auf neueren Delphi Versionen könntest du ReportMemoryLeaksOnShutdown := true; als erste Zeile der dpr setzen und würdest Memoryleaks dann beim Programmende angezeigt bekommen.

Und TDictionary aus Generics.Collections wäre auch sicher eine einfache und brauchbare Lösung für deine Problemstellung.

Uwe Raabe 10. Jun 2020 20:42

AW: IntStringList und Objektfreigabe
 
Zitat:

Zitat von Shark99 (Beitrag 1466955)
Meine Frage ist ob ich die Integers die in Objects[] gespeichert werden vor dem .Free einer Instanz so Liste einzeln manuell freigeben muss, damit kein Speicherleck entsteht?

Genau genommen darfst du die gar nicht freigeben, da es ja keine wirklichen Objekte sind. Du gaukelst das zwar dem Compiler vor, aber real sind das ja wirklich nur Integer. Das könnte sogar hörbar krachen, wenn du die frei gibst.

TiGü 11. Jun 2020 08:56

AW: IntStringList und Objektfreigabe
 
Zitat:

Zitat von TurboMagic (Beitrag 1467020)
Beantwortung der Originalfrage: ja, die müssen freigegeben werden.
Wärst du auf neueren Delphi Versionen könntest du ReportMemoryLeaksOnShutdown := true; als erste Zeile der dpr setzen und würdest Memoryleaks dann beim Programmende angezeigt bekommen.

Und TDictionary aus Generics.Collections wäre auch sicher eine einfache und brauchbare Lösung für deine Problemstellung.

Es fällt mir in letzter Zeit auf, dass einige Mitforisten nur noch das Ursprungsposting lesen und gar nicht mehr die schon gegebenen Antworten (auch die des Threaderstellers), in denen schon alles gesagt wurde.

Was ist das? Faulheit? Dummheit? Boshaftigkeit? Oder ein "Ich-will-auch-irgendwas-schreiben"?

dummzeuch 11. Jun 2020 10:06

AW: IntStringList und Objektfreigabe
 
Eigentlich hat Uwe die Frage ja schon beantwortet, aber da gerade eine falsche Antwort kam:

(Dies gilt für Delphi 7 und alle neueren Versionen für den 32 Bit Windows Compiler)

TObject(IntegerVariable) ist lediglich ein Typecast, es erzeugt kein Objekt und deshalb darf auch keines freigegeben werden. Ich hätte dort allerdings nicht nach TObject sondern nach Pointer gecastet.

Und da TStringList die Objekte nicht selbst verwaltet, sondern nur die Pointer speichert, besteht auch keine Gefahr, dass irgendwo in der RTL versucht wird die (Pseudo-)Objekte freizugeben. Also alles gut.

TurboMagic 11. Jun 2020 10:09

AW: IntStringList und Objektfreigabe
 
Zitat:

Zitat von TiGü (Beitrag 1467038)
Zitat:

Zitat von TurboMagic (Beitrag 1467020)
Beantwortung der Originalfrage: ja, die müssen freigegeben werden.
Wärst du auf neueren Delphi Versionen könntest du ReportMemoryLeaksOnShutdown := true; als erste Zeile der dpr setzen und würdest Memoryleaks dann beim Programmende angezeigt bekommen.

Und TDictionary aus Generics.Collections wäre auch sicher eine einfache und brauchbare Lösung für deine Problemstellung.

Es fällt mir in letzter Zeit auf, dass einige Mitforisten nur noch das Ursprungsposting lesen und gar nicht mehr die schon gegebenen Antworten (auch die des Threaderstellers), in denen schon alles gesagt wurde.

Was ist das? Faulheit? Dummheit? Boshaftigkeit? Oder ein "Ich-will-auch-irgendwas-schreiben"?

Nein. Ich hab' einfach vor lauter Beiträge Lesen überlesen, dass der gute ja Integers in dem Platzhalter für Objekte speichern will.
Die darf man natürlich nicht freigeben! Sorry!

himitsu 11. Jun 2020 10:41

AW: IntStringList und Objektfreigabe
 
Zitat:

Zitat von TurboMagic (Beitrag 1467046)
Integers in dem Platzhalter für Objekte speichern will.
Die darf man natürlich nicht freigeben!

Außer er speichert in dem TObject wirklich eine Objektinstanz, :angle:
wo dann das OwnsObjects=True liebendgern die Freigabe übernehmen würde.
Delphi-Quellcode:
type
  TMyDataObject = class
    FValue: Integer
    constructor Create(Value: Integer);
  end;
 
function TIntStringList.AddInteger(const s: string; i: integer): Integer;
begin
  ...
  //InsertItem(Result, S, TObject(i));
  InsertItem(Result, S, TMyDataObject.Create(i));
end;

Dennis07 11. Jun 2020 10:59

AW: IntStringList und Objektfreigabe
 
Kurze Klarstellung bzgl TDictionary: Das hier ähnelt wohl eher einer TList<TPair<String, Integer>> als einem TDictionary<String, Integer>, denn es können ja Duplikate im Schlüssel vorkommen.
Die Frage, wieso man Abwärtskompatibilität bis runter nach Delphi 7 bewahren muss stell ich an dieser Stelle mal auch besser nicht, denn erstens ist Delphi 7 mittlerweile so gut wie gar nicht mehr im Gebrauch, und zweitens benötigt man ja kein Delphi 10 nur um dann mit Delphi 7 Features entwickeln zu dürfen. Aber sei's drum...

Es stellt sich mit dennoch die Frage, wieso hier die TStringList so enorm Zweckentfremdet wird, dafür Kann man sich ja eigentlich ziemlich schnell etwas vernünftiges bauen. Problem ist nämlich, genau wie beschrieben, dass es bei falscher Anwendung oder ARC-Compilern schnell am krachen tun ist.
(Was passiert wenn ich aus Versehen die OwnsObjects-Eigenschaft benutze?)

himitsu 11. Jun 2020 13:05

AW: IntStringList und Objektfreigabe
 
Zitat:

Zitat von Dennis07 (Beitrag 1467053)
Die Frage, wieso man Abwärtskompatibilität ...

Zitat:

Weil ich ein Delphi 7 Projekt erweitere und es da kein TDictionary gib
Gut, man könnte natürlich auch das Projekt mal auf was Aktuelleres hochziehn, aber Jedem das Seine.

Shark99 11. Jun 2020 13:45

AW: IntStringList und Objektfreigabe
 
Das Projekt hat 80.000 Zeilen Code. Es von Delphi 7 auf 10.4 hochzuziehen würde sicher zu einem Umschreiben von 10% des Code resultieren. Es werden auch mindestens 20 Komponenten verwendet die mit Delphi XE1+ gar nicht funktionieren und ersetzt werden müssten. Dazu würde sich die Exe Größe durch den Umstieg sicher verdreifachen. Ein Fenster mit einem Button hat in Delphi 10 schon eine riesige Größe in Vergleich zu Delphi 7.

dummzeuch 11. Jun 2020 14:55

AW: IntStringList und Objektfreigabe
 
Zitat:

Zitat von Dennis07 (Beitrag 1467053)
(Was passiert wenn ich aus Versehen die OwnsObjects-Eigenschaft benutze?)

Die es, soweit ich mich erinnere, in Delphi 7 noch nicht gab. ;-)

Dalai 11. Jun 2020 18:46

AW: IntStringList und Objektfreigabe
 
Zitat:

Zitat von dummzeuch (Beitrag 1467069)
Zitat:

Zitat von Dennis07 (Beitrag 1467053)
(Was passiert wenn ich aus Versehen die OwnsObjects-Eigenschaft benutze?)

Die es, soweit ich mich erinnere, in Delphi 7 noch nicht gab. ;-)

TObjectList.OwnsObjects gibt es seit mindestens Delphi 5.

Grüße
Dalai

Uwe Raabe 11. Jun 2020 18:54

AW: IntStringList und Objektfreigabe
 
Zitat:

Zitat von Dalai (Beitrag 1467089)
TObjectList.OwnsObjects gibt es seit mindestens Delphi 5.

Hier geht es aber um TStringList.

Dalai 11. Jun 2020 19:45

AW: IntStringList und Objektfreigabe
 
Ups, hab ich offenbar verwechselt. Sorry.

Grüße
Dalai

TurboMagic 11. Jun 2020 22:30

AW: IntStringList und Objektfreigabe
 
Zitat:

Zitat von Dennis07 (Beitrag 1467053)
Kurze Klarstellung bzgl TDictionary: Das hier ähnelt wohl eher einer TList<TPair<String, Integer>> als einem TDictionary<String, Integer>, denn es können ja Duplikate im Schlüssel vorkommen.

TDictionary kann m.W. auch so eingestellt werden, dass Duplikate erlaubt sind.
Ist vielleicht nicht ganz im Sinne des Erfinders, aber geht glaube ich schon.

Shark99 11. Jun 2020 23:21

AW: IntStringList und Objektfreigabe
 
mit .Sorted := True sind auch bei TIntStingList keine Duplikate erlaubt.

DeddyH 12. Jun 2020 08:41

AW: IntStringList und Objektfreigabe
 
Nicht ganz: um Duplicates auf dupIgnore setzen zu können, muss außerdem Sorted auf true gesetzt sein, so wird ein Schuh draus.

freimatz 15. Jun 2020 09:20

AW: IntStringList und Objektfreigabe
 
Zitat:

Zitat von Dennis07 (Beitrag 1467053)
Die Frage, wieso man Abwärtskompatibilität bis runter nach Delphi 7 bewahren muss stell ich an dieser Stelle mal auch besser nicht, denn erstens ist Delphi 7 mittlerweile so gut wie gar nicht mehr im Gebrauch, und zweitens benötigt man ja kein Delphi 10 nur um dann mit Delphi 7 Features entwickeln zu dürfen. Aber sei's drum...

Die Antwort auf diese nicht gestellte Frage gebe ich nicht :wink: aber es gibt auch in aktuellen Projekten mit 500.000 oder 1.7 Millionen Zeilen Code noch etliche Teile, die mit D7 entwickelt wurden. (Und es gibt auch noch Code von Turbo-Pascal 3.0)

Shark99 15. Jun 2020 09:30

AW: IntStringList und Objektfreigabe
 
Es geht darum, dass Delphi 7 extrem populär war und dafür tausende Komponenten entwickelt wurden, die dann nicht nach Delphi 2007/2009/XE konvertiert wurden. Da Delphi 2007 und 2009 dazu noch beim Release extrem buggy waren sind viele Projekte bei Delphi 7 steckengeblieben und werden bis heute gepflegt.

Ich nutze neben Delphi 7 vor allem Delphi XE5, und die UI von Delphi 7 fühlt sich sensationell schnell an. Die Suchfunktion ist auch leichter zu beutzen. Bleibt man bei Win32 gibt es dank CNPack und GExperts bis auf 64bit Unterstützung kaum Nachteile zu Delphi XE.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:47 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz