![]() |
Typisierten bzw. Untypisierten Variablen
Ich habe mir gerade das Stammtisch AVI über die Typisierten bzw. Untypisierten Variablen angesehen.
Der Protagonist hat da eine Bemerkung über Tlist abgegeben die mir ein bisschen missfällt. Frei Zitiert findet er Tlist, deswegen nicht so überzeugen, weil Tlist Speicherplätze im Vorrat für sich beansprucht. Bei Verketten-Listen kann ich nicht direkt über einen Index auf den Datensatz zugreifen. Mir ist nicht bekannt wie das ohne Tlist gehen soll. Im Zweifen muss man alle Datensätze druchlaufen um den richtigen zu finden. Auch beim Sortieren ohne Tlist, ich brauche mit den Ding nur die Adr. zu tauschen, anders tun sich einige Probleme auf. Ich finde Tlist ist eine feine Sache. Allerdings hat der Protagonist auf eine Sache aufmerksam gemacht, die ich so noch nie betrachtet hatte. Und zwar das strings mir Speicherlecks machen können. Folgenden Standart nutze ich in der Regel. Muss ich dort meine Strings auf doppelt Null setzen um keine Leckes zu haben? Und wie ist das bei z.B. normalen integer Variablen. Der Speicher wird im Zweifeln immer noch den Wert haben auch wenn darauf kein Zeiger zeigt. Bleib da jetzt ein Leck und wenn ja wie kann man das verhindern.
Delphi-Quellcode:
type
PDateiListRec = ^TDateiListRec; TDateiListRec = packed record SRec : TSearchRec Pfad : string; DateiName : string; …. end; var FdateiRecList : Tlist; procedure TDhDrive.ListRec_Delete(Index:integer); begin if not Assigned(FDateiRecList) or (not FDateiRecList.Count > 0) then Exit; Dispose(PDateiListRec(FDateiRecList[Index])); with FDateiRecList do begin Delete(Index); Pack; Capacity := Count; end; end; //-------------------------------------------------------------------------------------------------- procedure TDhDrive.ListRec_Clear; begin while FDateiRecList.Count > 0 do ListRec_Delete(0); FDateiRecList.Clear; end; //-------------------------------------------------------------------------------------------------- procedure TDhDrive.ListRec_Free; begin ListRec_Clear; FreeAndNil(FDateiRecList); end; //-------------------------------------------------------------------------------------------------- procedure TDhDrive.ListRec_Add(Directory:string;SR:TSearchRec); var; P : pointer; begin with SR do begin P := new(PDateiListRec); FillChar(PDateiListRec(P)^, SizeOf(PDateiListRec(P)^), 0); with PDateiListRec(P)^ do begin SRec := SR; FDateiRecList.Add(P); end; end; |
Re: Typisierten bzw. Untypisierten Variablen
New als Funktion?
Ich kenn das nur als Prozedur :gruebel:
Delphi-Quellcode:
Also nun zum Problem:
procedure TDhDrive.ListRec_Add(Directory:string;SR:TSearchRec);
var; P : PDateiListRec; begin //with SR do // ich wüßte jetzt nicht, wofür das nötig sein sollte? *grübel* //begin New(P); FillChar(P^, SizeOf(P^), 0); PDateiListRec(P)^.SRec := SR; FDateiRecList.Add(P); //end; end; Dispose ruft die Prozedur Finalize auf und übergibt diesem den Record, bevor es selber den Speicher des Records mit FreeMem freigibt. Finalize "löscht" alle initialisierungspflichtigen Typen von Delphi, also > Strings (Ansi, Wide & Unicode), dynamische Arrays und Interfaces Genauso wie New die Prozedur Initialize aufruft und diese Typen entsprechend initialisiert (quasi mit 0 füllt), nachdem es mit GetMem den Speicher des Records besorgt hat. Wenn es dir also nicht wichtig ist, daß z.B. auch Integer und Objectvariablen unbedingt mit 0 initialisiert werden, da sie danach eh mit irgendwas gefüllt werden, dann könntest du dein FillChar auch weglassen. |
Re: Typisierten bzw. Untypisierten Variablen
@TList: Wenn es nur um den Komfort des indizierten Zugriffs geht, kann ich eine Listenklasse so bauen, dass intern eine doppelt verkettete verwaltet wird, und indizierten Zugriff nach aussen "simuliert", intern aber die Liste traversiert. Ist halt nicht so prima bei sehr großen Listen bei denen es auf Performance ankommt, wobei ich hier die Idee hätte ein festes Array mit N Elementen zu nehmen, dass auf jedes ElementCount/Nte Element zeigt, so dass man bei dem quasi indizierten Zugriff schon mal nah dran ist bevor man sich weiter hangelt. Also, Mittel und Wege gäbe es da schon will ich damit nur sagen :) Auch wenn es eigentlich etwas OT ist...
|
Re: Typisierten bzw. Untypisierten Variablen
Bezüglich TList, auch wenn die Gefahr besteht, das das Thema abdriftet:
Die TList-Klasse wurde nach dem ![]() Eine einfach verkettete Liste benötigt pro Element 8 Bytes Speicherplatz (4 Bytes Nutzinformation + 4 Bytes Vorwärtsverkettung), eine doppelt verkettete Liste sogar 12 Bytes. Das ist die doppelte bzw. dreifache Menge des wirklich Nötigen. Und eine TList? Die Nutzinformation wird in einem Array-Element gespeichert, der Verbrauch liegt also bei 4 Bytes pro Element. Dazu kommt noch der ungenutzte Bereich des Arrays am Ende: Wenn die Liste wachsen muss, tut sie das nicht in Einerschritten, sondern in 4er, 16er bzw. N/4-Schritten (bei mehr als 64 Elementen). Der maximale Overhead pro Element liegt also bei 25%. Eine TList ist also im Vergleich hinsichtlich des Speicherverbrauches wesentlich kompakter als eine verkettete Liste. @Medium: Dein Ansatz mit einem Hilfsarray... Was wäre das? Eine TList? :mrgreen: |
Re: Typisierten bzw. Untypisierten Variablen
Mir ist schon so zu 99% klar was ich da mache.
Vielleicht habe ich mich auch nicht klar genug ausgedrückt. Mir ging es nur darum dass der Vortragende (Name habe ich nicht im Kopf sorry) was von Speicherlecks erzählte die ich so nicht betrachtet hatte und das er Tlist, so kam es bei mir an nicht grade befürwortet. Das mit dem ungenutzen Speicher bei Tlist lässt ich einfach verhindern siehe Hilfe/ Capacity. Das kann ja bei X Gbyte, je Rechner der Grund sein. Mir ging es im wesendlichen um die Frage nach Speicherlecks, die Film auftrat. Und zwar dann wenn ich die Liste Freigebe. Das war im übrigen auch eine Frage aus dem im Hindergrund laufenden Forum. Bei 10.000 Daten mit jeweils eine, mehere String-Vari von 1.000 KB, könnte sich schon ein richtiges Loch ergeben. Vorallem dann wenn man seine Funktion merfach aufruft. Wie geht W-Doof mit diesen Löcher um, summiert sich das ganze, auch nach Freigabe? Dass könnte im Extremfall beteuten, das mein Rechner abnippelt obwohl ich vordergründing den Speicher freigegeben habe Das andere hat sich so aus dem Film ergeben (Im übrigen ist die Reihe prima) Ich nutze Tlist selber regelmäßig. Da ich das schon lange mache könnte es ja sein das ich was neues gelehrt habe, oder wenigstens die Sache aus einen anderen Blickwinkel sehe. Da ich hier vor Ort keine Leute habe mit denen man sich austauschen kann, fummele ich immer mehr oder weniger alleine vor mich hin. Dementsprechend muss, dass was ich mache nicht unbedingt der Weisheit letzter Schluss sein. Es soll daher keine Kritik sein. Ich hatte mich nur gewundert. Fällt mir gerade so ein, wer sich mit dieser Art Grundlagen beschäftigen möchte, dem kann ich das Buch von Data Becker Turbo-Pascal empfehlen. Heute gibt es das Buch für 2,xx € bei Ebay. Die meisten Sachen kann man dort auch heute noch 1 zu 1 übernehmen. @himitsu Warum SR! Das Teil habe ich bei mir aus einem PRG von mir als Muster herauskopiert um zu zeigen wie ich es in der Regel mache. Es ist ist ohne weitere Bedeudung. Ich war nur zu faul dort war zu ändern. Warum FillChar! Um String Vari leer zu haben um nicht immer X:=’’ schreiben zu müssen, oder boolean auf false zu haben. Auch das mache ich so immmer. Ich hoffe jetzt habe ich mich klar ausgedrückt. Ansonsten last Gnade mit einen alten, verwirrten Mann walten. *g |
Re: Typisierten bzw. Untypisierten Variablen
Hi Opa, ich habe dich in der Tat nicht richtig verstanden, aber meine Ausführungen bezüglich TList berührten dein Problem ja auch nur am Rande.
Von Speicherlecks bei der TList-Klasse ist mir nichts bekannt. Es wäre ja auch noch schöner. Meine Erfahrung ist, das ich bei Einhaltung der Grundprinzipien de Speicheralloziierung keine Speicherlecks bekomme. Nie. |
Re: Typisierten bzw. Untypisierten Variablen
Stammtisch-Video?! Hab ich was verpasst?
|
Re: Typisierten bzw. Untypisierten Variablen
![]() |
Re: Typisierten bzw. Untypisierten Variablen
Zitat:
|
Re: Typisierten bzw. Untypisierten Variablen
@alzaimar
ich kann dir beim "Speicherverbrauch" bei Tlist und doppelt verketteter Liste nicht ganz folgen. praktischer Weise benötige ich neben den Nutzdaten für die doppelt verkettete Liste drei Zeigervariablen (Anfang,Ende,Aktuell) sowie zwei Zeiger pro Datensatz(record). Bei der Tlist benötige ich mindestens einen Zeiger pro Datensatz (und noch ein bischen internen Verwaltungs aufwand). Bei größeren Mengen an Datensätzen ist der Platzbedarf (für die Speicheradressierung) nur doppelt so hoch, Und bei der einfachen Verkettung sollte er gleich sein. Und mit wieviel Speicheraufwand wird der direkte Zugriff in Tlist bezahlt? Gruß K-H |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:20 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz