Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Typisierten bzw. Untypisierten Variablen (https://www.delphipraxis.net/141177-typisierten-bzw-untypisierten-variablen.html)

Opa 4. Okt 2009 01:18


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;

himitsu 4. Okt 2009 01:41

Re: Typisierten bzw. Untypisierten Variablen
 
New als Funktion?
Ich kenn das nur als Prozedur :gruebel:

Delphi-Quellcode:
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;
Also nun zum Problem:
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.

Medium 4. Okt 2009 04:58

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...

alzaimar 4. Okt 2009 08:26

Re: Typisierten bzw. Untypisierten Variablen
 
Bezüglich TList, auch wenn die Gefahr besteht, das das Thema abdriftet:
Die TList-Klasse wurde nach dem KISS-Prinzip erstellt. Sie ist schnell, kompakt und leicht verständlich. Wer allen Ernstes den Speicherverbrauch als Argument angibt, kennt die TList-Klasse nicht. Die Aussage ist schlicht und ergreifend falsch:

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:

Opa 4. Okt 2009 13:52

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

alzaimar 4. Okt 2009 14:08

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.

richard_boderich 4. Okt 2009 14:56

Re: Typisierten bzw. Untypisierten Variablen
 
Stammtisch-Video?! Hab ich was verpasst?

mleyen 4. Okt 2009 15:08

Re: Typisierten bzw. Untypisierten Variablen
 
hier das Video "[#12.2] Aufzeichnung 2. virtueller Delphi-Stammtisch, Teil 2 von 4"

Medium 4. Okt 2009 15:52

Re: Typisierten bzw. Untypisierten Variablen
 
Zitat:

Zitat von alzaimar
@Medium: Dein Ansatz mit einem Hilfsarray... Was wäre das? Eine TList? :mrgreen:

Ne :) Ich meinte ja ein Array fester Länge, mit dem man einfach nur die Möglichkeit hätte "mitten rein" zu greifen, also in die eigentliche dopp. verkettete Liste. Ist natürlich aber auch wieder Verwaltungsaufwand. Ich bin ja auch kein TList-Verächter, ich wollte nur sagen dass man sich sowas in der Richtung auch konstruieren könnte. Ob's sinnvoll ist hängt wie so oft mal wieder vom konkreten Einsatzzweck ab :)

p80286 5. Okt 2009 16:16

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 14:02 Uhr.
Seite 1 von 2  1 2      

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