Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   FreeMem vs. Dispose bei TList of Record (https://www.delphipraxis.net/162830-freemem-vs-dispose-bei-tlist-record.html)

Bjoerk 6. Sep 2011 18:06

Delphi-Version: 2007

FreeMem vs. Dispose bei TList of Record
 
Ich habe eine TList, mit der ich Dateien miteinander vergleichen möchte.

Items werden so hinzugefügt:
Delphi-Quellcode:
type
  TItem = record
    FileName: string;
    FileSize: integer;
    FileMem: Pointer;
  end;

procedure TItemList.AddItem(Item: TItem);
var
  P: PItem;
begin
  New(P); // ***
  P^:= Item;
  Add(P);
end;
Die Dateien werden so eingelesen:

Delphi-Quellcode:
procedure TForm1.getFiles(const Path, Mask: string);
var
  SearchRec: TSearchRec;
  Result, R: integer;
  Item: TItem;
  F: File;
begin
  Result:= findFirst(Path+Mask, faArchive, SearchRec);
  while Result = 0 do
  begin
    Item.FileName:= Path+SearchRec.Name;
    Item.FileSize:= SearchRec.Size;

    AssignFile(F, Item.FileName);
    GetMem(Item.FileMem, Item.FileSize); // ***
    Reset(F, 1);
    BlockRead(F, Item.FileMem^, Item.FileSize, R);
    CloseFile(F);

    ItemList.AddItem(Item);
    Result:= findNext(SearchRec);
  end;
  findclose(SearchRec);
end;
Verglichen werden die Dateien anschließend mit CompareMem.

Die Liste wird so gelöscht:
Delphi-Quellcode:
procedure TItemList.DelItem(Index: integer);
var
  P: PItem;
begin
  P:= Items[Index];
  FreeMem(P.FileMem); // ***
  Dispose(P); // ***
  Delete(Index);
end;

procedure TItemList.ClearList;
begin
  while Count > 0 do DelItem(Count-1);
end;
Meine Frage ist jetzt, ob das FreeMem in DelItem Blödsinn ist, oder muß mit GetMem angeforderter Speicher auf jeden Fall mit FreeMem freigegeben werden?

himitsu 6. Sep 2011 19:02

AW: FreeMem vs. Dispose bei TList of Record
 
Natürlich mußt du diesen Speicher auch wieder freigeben, ABER

- mit Delphi-Referenz durchsuchenNew reserviert = mit Delphi-Referenz durchsuchenDispose freigeben
- mit Delphi-Referenz durchsuchenGetMem reserviert = mit Delphi-Referenz durchsuchenFreeMem freigeben
- mit Delphi-Referenz durchsuchenCreate reserviert = mit Delphi-Referenz durchsuchenFree freigeben
usw.
New + FreeMem paßt allerdings nicht zusammen :warn:

PS: Deswegen wurde dir ja auch mal TObjectList+Datenobjekt vorgeschlagen, denn der TObjectList kann man sagen, daß sie Owner (Besitzer) der Objekte ist, mit dem Ergebnis, daß die Objektliste sich um das Freigeben kümmert.

Ab D2009 gibt es dann noch die generische TList<>, welche sich um die Verwaltung ihres enthaltenden Datentyps kümmert.
(
Delphi-Quellcode:
TList<TMyRecord>
hat quasi das New und Dispose schon eingebaut)

shmia 6. Sep 2011 19:34

AW: FreeMem vs. Dispose bei TList of Record
 
Jenachdem was der Dateivergleich leisten soll, braucht man unterschiedliche Strategien.
Wenn zwei Dateien unterschiedliche Längen haben, dann können sie nicht gleich sein.
Dies sollte man ganz zu Beginn prüfen, bevor man unnötigerweise eine oder mehrere Dateien eingelesen hat.

Möchte man einfach nur zwei Dateien vergleichen, dann sollte man diese blockweise (z.B. 4kByte) einlesen und bei einem Unterschied kann sofort abgebrochen werden.
Das ist ein Riesenvorteil wenn man z.B. zwei Dateien mit jeweils 3 GByte vergleichen möchte und schon nach 16 kByte ein Unterschied aufgetreten ist.

Möchte man dagegen Duplikate finden und dazu jede Datei mit jeder anderen vergleichen,
dann ist es auch nicht ratsam sämtliche Dateien in den Hautpspeicher zu laden.
Stattdessen bildet man eine Prüfsumme (z.B. MD5, SHA-320,...) über alle Dateien und vergleicht nur die Prüfsummen.
Das spart enorm viel Speicher.

Bjoerk 6. Sep 2011 19:40

AW: FreeMem vs. Dispose bei TList of Record
 
Zitat:

Zitat von himitsu (Beitrag 1122216)

PS: Deswegen wurde dir ja auch mal TObjectList+Datenobjekt vorgeschlagen [..]

Ähm, wann ? Von wem ?

Ich danke dir für die Antwort. Müßte bei einer ObjectList (in diesem Fall) nicht auch GetMem/FreeMem erfolgen ??

himitsu 6. Sep 2011 20:16

AW: FreeMem vs. Dispose bei TList of Record
 
In einer TObjectList legt man ja überlicher Weise Objekte ab :zwinker:
- die erstellt man einmal mit Create und gibt sie mit Free frei
- steht OwnsObjects auf True, dann ruft die Objektliste das Free auf, wenn ein Item gelöscht wird


Wo *überleg* ... in 'nem anderem Thread, aber jetzt wo du's sagst ... ich glaub ich hab dich verwechselt [SIZE="p"](passten wohl zu gut zusammen, die beiden Themen :oops: )[/SIZE]


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:44 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