AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Gibt TList.Delete darin befindliche Instanzen auch frei oder ?

Gibt TList.Delete darin befindliche Instanzen auch frei oder ?

Ein Thema von die Suchende · begonnen am 25. Jul 2011 · letzter Beitrag vom 25. Jul 2011
Antwort Antwort
die Suchende

Registriert seit: 27. Mär 2009
16 Beiträge
 
#1

Gibt TList.Delete darin befindliche Instanzen auch frei oder ?

  Alt 25. Jul 2011, 13:24
Hallo zusammen,

ich bin jetzt ein bischen mehr als zwei Jahre dabei (Delphi5) und das meiste funktioniert auch gut. Allerdings merke ich selbst, dass ich vieles nur so mache, dass es funktioniert ... der Stil ist noch nicht besonders gut und da habe ich mal eine Frage ...

Kurz noch vorne weg:
Wir lesen Daten aus einem Gerät aus (Datensatz ist "string") oder aus Dateien ein (Textdateien, ini, datensatz ist string). Ich arbeite also mit StringListen, wobei der erste "String" der StringList das Datum enthält und danach kommen die anderen Daten. Nun habe ich ja mehrere Datensätse also viele StringListen ... Da habe ich nun angefangen mit TList zu arbeiten. Die Liste aus Stringlisten lässt sich auch recht gut wieder auf der Oberfläche darstellen (TStringGrid).

Nun meine Frage, ob der folgende Code so korrekt ist - der Code ist ein bischen abgekürzt

Delphi-Quellcode:
procedure Dateneinlesen;
var List: TList;
    strList: TStringList;
    i, j: integer;
begin
  List := TList.Create;
  try

    //gehe Stringgrid durch und merke dir die alten Daten
    // StringGrid hat Tabellenkopf
    // Anzahl der Spalten ist der Anzahl "Datum + Daten im Datensatz" bereits angepasst
      for i:=1 to StringGrid.RowCount-1 do begin
          strList := TStringList.Create;

          strList.add('0'); //alter Datensatz

          for j:=0 to StringGrid.ColCount-1 do begin
              strList.add(StringGrid.Cells[j,i]);
          end;

          List.Add(strList);
      end;

    //---------
    //neue Daten einlesen
    // Datei öffnen
    ...

    //Daten einlesen
    repeat
      strList := TStringList.Create;

      strList.add('1'); //neue Daten

      strList.add(andere Daten);
 
      List.add(strList);
    until keine anderen Daten mehr

    //Datei schließen
    ...

    //--------
    
    //Liste nach Datum sortieren ... steht in allen Datensätzen natürlich an der gleichen Stelle
    //hier nicht weiter beschrieben
    ListeVonStrListenNachDatumSortieren(List,
               StrListSpalteDatum, BeginnInListe, EndeInListe);

    //Doppelte löschen
    ListeVonStrListenDatumDoppelteRaus(List, StrListSpalteDatum);

    //--------
    //Auf der OF anzeigen

    // alte Daten aus StringGrid löschen
    StringGrid.RowCount := 2;
    for j:=0 to StringGrid.ColCount-1 do begin
        StringGrid.Cells[j,1] := '';
    end;

    //sortierte Daten ohne Doppelte eintragen
    for i:=0 to List.Count-1 do begin
        if StrinGrid.Cells[0,1] <> 'then StringGrid.RowCount := StringGrid.RowCount +1;

        strList := List.Item[i];
        for j:=1 to strList.Count-1 do begin
            //im ersten Element, steht nur, ob der Datensatz alt oder neu ist ... deshalb bei j=1 anfangen

            if j > StringGrid.ColCount-1 then begin
               StringGrid.Cells[j, i] := strList.Strings[j];
            end else begin
               breake; //was auch immer hier noch drin steht, was nicht drin stehen soll
            end;
        end;
    end;

  //--------
  finally
   for i:=0 to List.Count-1 do begin
       strList := List.item[i];
       strList.free;
   end;
   List.Free;

  end;
end;
Delphi-Quellcode:
procedure ListeVonStrListenDatumDoppelteRaus(List: TList;
                 StrListSpalteDatum: integer);
var strList1, strList2: TStringList;
    i: integer;
begin
  if List.Count < 1 then exit;

  i:=0;
  repeat
      strList1 := List.Items[i];
      strList2 := List.Items[i+1];

      if (strList1.Count > 0) and (strList2.Count > 0) then begin
         if strList1.strings[StrListSpalteDatum] = strList2.strings[StrListSpalteDatum] then begin
           if strList1.strings[0] = '0then begin
              strList1.free;
              List.Delete(i);
           end else begin
              strList2.free;
              List.Delete(i+1);
           end;
           //Doppelte dürfen/ können nicht da sein
           //Entweder das eine oder das andere ist falsch
         end else begin
           inc(i);
         end;
      end else begin
         inc(i); //sonst komm ich aus der Schleife nicht wieder raum
                 //aber, was sind das für komische Stringlisten
                 // strList.Strings[0] = ob alt oder neu
                 // strList.strings[strListSpalteDatum] = Datum
                 // und Rest?
      end;
  until i >= List.Count-2;

  //nochmal letzten Beiden kontrollieren
  //kann nicht am Anfang der Schleife inc(i) machen, weil
  // wenn ein Element/Item gelöscht wird soll er ja nicht hoch zählen
  // -> am Ende nochmal kontrollieren
  strList1 := List.Items[List.Count-2];
  strList2 := List.Items[List.Count-1];
  if (strList1.Count > 0) and (strList2.Count > 0) then begin
     if strList1.strings[StrListSpalteDatum] = strList2.strings[StrListSpalteDatum] then begin
       if strList1.strings[0] = '0then begin
          strList1.Free;
          List.Delete(List.Count-2);
       end else begin
          strList2.Free;
          List.Delete(List.Count-1);
       end;
     end;
  end;

end;
Was ist eigentlich, wenn man die StringListen, die in der List stecken, nicht frei gibt und nur List.free macht. Ist der speicher dann noch belegt, aber es zeigt nichts mehr darauf oder kann der Speicher dann wieder verwendet werden, aber es ist einfach schlechter Stil?
Oder muss ich das mit den StringList.free gar nicht machen? In der Hilfe steht nämlich:
"
Soll lediglich die Referenz auf ein Element gelöscht werden, ohne das Element selbst zu entfernen und den Wert von Count zu ändern, setzen Sie die Eigenschaft Items für Index auf nil.
"
Wenn ich mit List.Delete(i) eine Instanz=TstringList lösche, ist dann der Speicher wieder richtig freigegeben oder ist nur der Pointer gelöscht? Wenn ich zuvor schon die StringListe freigegeben habe, hat doch der Pointer gar nichts mehr auf das er in dem Moment zeigt? Oder ist dem Pointer das egal, weil er eh nur auf eine beliebige Adresse im Speicher zeigt?


Wenn euch noch weitere Fehler auffahlen, wäre ich über jede Korrektur sehr dankbar! Z.B. habe ich das Gefühl, dass die Tabelle (StringGrid) nich korrekt gelöscht wird, nur weil ban die Zeilenanzahl zurücksetzt... aber da das ein anderes Thema ist, wollte ich das hier nicht weiter ausmahlen.


Ich danke euch schon mal im Vorraus für den Support.
die Suchende
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.557 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Gibt TList.Delete darin befindliche Instanzen auch frei oder ?

  Alt 25. Jul 2011, 13:28
Das kannst Du recht einfach herausfinden, indem Du ReportMemoryLeaksOnShutdown auf true setzt. AFAIK gibt TList keine Instanzen frei, da seine Elemente vom Typ Pointer sind und nicht von TObject. Du kannst aber beispielsweise auf eine TObjectList ausweichen und deren Eigenschaft OwnsObjects auf true lassen(Voreinstellung), dann hast Du das gewünschte Verhalten.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
schlecki

Registriert seit: 11. Apr 2005
Ort: Darmstadt
148 Beiträge
 
Delphi XE2 Enterprise
 
#3

AW: Gibt TList.Delete darin befindliche Instanzen auch frei oder ?

  Alt 25. Jul 2011, 13:54
Das kannst Du recht einfach herausfinden, indem Du ReportMemoryLeaksOnShutdown auf true setzt. AFAIK gibt TList keine Instanzen frei, da seine Elemente vom Typ Pointer sind und nicht von TObject. Du kannst aber beispielsweise auf eine TObjectList ausweichen und deren Eigenschaft OwnsObjects auf true lassen(Voreinstellung), dann hast Du das gewünschte Verhalten.
Dafür muss man aber FastMM4 einbinden. In Delphi 5 ist das noch nicht eingebaut, iirc
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.371 Beiträge
 
Delphi 12 Athens
 
#4

AW: Gibt TList.Delete darin befindliche Instanzen auch frei oder ?

  Alt 25. Jul 2011, 14:24
TList gibt nichts frei.
Es gibt es auch nicht umsonst die TObjectList, bei welcher man dann OwnsObjects auf true setzt, damit die Objekte freigegeben werden.

[edit] komisch, grade fehlten noch ein paar Beiträge
OK, also in Delphi 5 sieht es da wohl schlecht aus ... dort dußt du es also selber freigeben, bzw. du leitest dir die TObjectList ab und rüstest das OwnsObjects selber nach.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (25. Jul 2011 um 14:28 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.557 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Gibt TList.Delete darin befindliche Instanzen auch frei oder ?

  Alt 25. Jul 2011, 17:10
Das Delphi 5 habe ich glatt überlesen, obwohl es klar und deutlich da steht. Ist aber auch egal, dann lädt man es eben herunter und benutzt es dann (IIRC funktioniert FastMM auch schon unter D5, bin aber nicht zu 100% sicher).
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.418 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Gibt TList.Delete darin befindliche Instanzen auch frei oder ?

  Alt 25. Jul 2011, 17:13
Das geht sogar noch mit Delphi 4.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.371 Beiträge
 
Delphi 12 Athens
 
#7

AW: Gibt TList.Delete darin befindliche Instanzen auch frei oder ?

  Alt 25. Jul 2011, 17:46
Auch wenn FastMM einige Vorteile mitbringt (Speicherprüfung und vorallem daß dieser wesentlich schneller ist, als der alte DelphiMM),

aber verwirrt den armen Kerl doc nicht gleich.



Sein Problem lag ja eigentlich in der TList und da können wir so oder so zu 100% sagen, daß es nichts freigibt und das alte TObjectList noch nicht so otimal funktionierte.

Hatte die TObjektList damals eine Ereignismetode, für "Item wird gelöscht" ?
Wenn ja, dann könnte man diese ganz leicht benutzen und weg wäre das Problem.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
die Suchende

Registriert seit: 27. Mär 2009
16 Beiträge
 
#8

AW: Gibt TList.Delete darin befindliche Instanzen auch frei oder ?

  Alt 25. Jul 2011, 21:14
Danke, dass ihr so schnell geantwortet hat.

wie es scheint habe ich ja soweit alles richtig gemacht, außer dass ich statt TList gleich TObjectList hätte verwenden können.

Ist "FastMM" eine Komponente? Was kann man damit machen? Ich kenn mich damit noch nicht so aus. Ich habe erst ein paar freie Komonenten mit reingeladen, z.B. um die Größe der Objecte auf der Oberfläche, wie TChart, StringGrid, Edits, Buttons usw. anzupassen, wenn man die Fenstergröße verändert.
Übrigens sagt ihr bei eurem Beitrag: http://www.delphipraxis.net/56271-fa...n-langsam.html
, dass es auch nicht besser ist als "der normale MemoryManager von Delphi", auch wenn ihn noch nicht wissentlich verwendet habe.

auf jeden Fall nochmal danke
die Suchende
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:12 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