Einzelnen Beitrag anzeigen

NickelM

Registriert seit: 22. Jul 2007
Ort: Carlsberg
445 Beiträge
 
Delphi 2009 Professional
 
#12

AW: GetMem / FreeMem - New / Dispose

  Alt 8. Jun 2012, 13:09
Er meint dass wie folgt:
Delphi-Quellcode:
type
  TRecord1 = record
    Wert1 : Integer;
  end;
  PRecord1 = ^TRecord1;//Pointer auf die Daten des TRecord1.

  TRecord2 = record
   Record1 : PRecord1; //Eine Variable vom PRecord1
  end;
  PRecord2 = ^TRecord2;

//Wenn du dies nun wie folgt initalisiertst:
var Record2 : PRecord2;
begin
  GetMem(Record2,SizeOf(TRecord2)); //Speicher vom Record-Typ, nicht vom Pointer-Typ :-D
  GetMem(Record2.Record1,SizeOf(TRecord1)); //Den TRecord1-Pointer in TRecord2 initalisieren.
  Record2.Record1.Wert1 := 10; //Als Test

  //Wenn du dies nun wie folgt freigibst nur...
  FreeMem(Record2,SizeOf(TRecord2)); //Zur Sicherheit würd ich die Größe nochmal übergeben.
  //...bleibt der Pointer auf TRecord1 in TRecord2 enthalten, also der Speicher von TRecord1 wird nicht freigegeben. Weil in TRecord1 nur der Pointer(Adresse, wo TRecord1 seine Daten hat), also nur der Adresswert, freigegeben wird.
  //In diesem Fall müsste mal folgendes machen:
  FreeMem(Record2.Record1,SizeOf(TRecord1));//Alle in diesem Pointer-Record-Typ enthaltenen Pointer musst du selbst freigeben. Bei Klassen halt Free davor aufrufen.
  FreeMem(Record2,SizeOf(TRecord2));//Danach erst den "Oben"-Pointer freigeben.
end;
Du musst halt sozusagen die hierarchie deines Pointers, wenn du es so machst wie in dem Beispiel, von unten nach oben freigeben, erst die untengeordneten, danach die oberen.
Auserdem macht GetMem nur Platz für die Daten. Es ist meist so, dass dort Werte von anderen freigegeben Speichern noch liegt. Weil GetMem halt nur sagt, so hier kannst deine Daten reinschreiben. Es gibt aber auch noch die AllocMem, mit der dann der Speicher mit "0"Bytes aufgefühlt wird, um solche Fehler zuvermeiden. Das kann dan auch mit FreeMem freigegen werden.
Dies ist genauso als würdest du GetMem und danach FillChar aufrufen.

EDIT: Habe gerade was getestet. Bei New/Dispose werden Pointer initalisiert, die nach Dispose noch verfügbar sind. D.h. der Speicher wird von Delphi freigegeben. Sozusagen wenn du wirklich Kontrolle über den Speicher für solche Pointer haben willst verwende lieber, GetMem/FreeMem. Bei falscher verwendung können halt solche genannten Fehler entstehen.

Hoffe ich konnte es dir erklären. Ist ein wenig kompliziert am anfang, ging mir auch so .
Aber einmal kapiert, sind Pointer und Speicher erstellen/freigeben ein kinderspiel xD
Nickel
"Lebe und denke nicht an morgen"
Zitat aus dem gleichnamigen Bollywoodfilm.

Geändert von NickelM ( 8. Jun 2012 um 13:34 Uhr)
  Mit Zitat antworten Zitat