Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Record zurücksetzen (löschen) (https://www.delphipraxis.net/120638-record-zuruecksetzen-loeschen.html)

Guido Eisenbeis 14. Sep 2008 01:11


Record zurücksetzen (löschen)
 
Delphi-Quellcode:
// Beispiel:

type
  TMyRecord = record
    Test_1:          string;
    Test_2:          string;
    Test_3:          string;
    Integer_1:       integer;
    Integer_2:       integer;
  end;

 ...

 MyRecord: TMyRecord;
Hi,

da ich bei meiner Suche nichts gefunden habe, ahne ich, dass ich da selbst Hand angelegt muss. Aber dennoch die Frage: Gibt es eine Delphi-Funktion um ein Record zu löschen? Also sowas wie MyRecord := nil? :gruebel:

Guido.


Edit: Ein Demo der Lösung, für die ich mich entschieden habe, befindet sich in Posting #63.

.

mr_emre_d 14. Sep 2008 01:26

Re: Record zurücksetzen (löschen)
 
Die Delphi-Hilfe:
Code:
Records (erweiterte)
Zusätzlich zu den traditionellen Record-Typen lässt die Delphi-Sprache komplexere und “klassenähnliche” Record-Typen zu. Zu den Feldern können Records Eigenschaften und Methoden (einschließlich Konstruktoren), Klasseneigenschaften, Klassenmethoden, Klassenfelder und verschachtelte Typen haben. Weitere Informationen hierzu finden Sie in der Dokumentation zu Klassen und Objekten. Im Folgenden finden Sie eine Beispiel-Record-Typdefinition mit einigen “klassenähnlichen” Merkmalen.
 
Obwohl Records nun einige der Merkmale von Klassen besitzen, gibt es wichtige Unterschiede zwischen Klassen und Records.
 
Records unterstützen keine Vererbung.
Records können variante Teile enthalten; Klassen nicht.
Records sind Wertetypen, daher werden Sie bei der Zuweisung kopiert, per Wert übergeben und dem Stack zugewiesen, wenn sie nicht als global definiert sind oder explizit mit den Funktionen New und Dispose zugewiesen werden. Klassen sind Referenztypen, daher werden Sie bei der Zuweisung nicht kopiert, per Referenz übergeben und dem Heap zugewiesen.
Records ermöglichen das Überladen von Operatoren auf Win32- und .NET-Plattformen; Klassen ermöglichen das Überladen von Operatoren nur bei .NET.
Records werden automatisch mit einem Standardkonstruktor ohne Argumente erzeugt, Klassen dagegen müssen explizit erzeugt werden. Weil Records einen argumentlosen Standardkonstruktor haben, muss jeder benutzerdefinierte Record-Konstruktor ein oder mehr Parameter haben.
Record-Typen können keine Destruktoren haben.
Virtuelle Methoden (die mit den Schlüsselwörtern virtual, dynamic und message angegeben werden) dürfen in Record-Typen nicht verwendet werden.
Im Gegensatz zu Klassen können Record-Typen auf der Win32-Plattform keine Schnittstellen implementieren; auf der .NET-Plattform können Records jedoch Schnittstellen implementieren.
[edit=Luckie]Neu abgschickt. Mfg, Luckie[/edit]

Guido Eisenbeis 14. Sep 2008 01:40

Re: Record zurücksetzen (löschen)
 
Warum schrummpelt den die Forum-Fensterdarstellung bei mir so zusammen?

Zum Thema: Ist da jetzt schon eine Antwort auf meine Frage drin? Dann bitte ein wenig genauer eingrenzen.

Danke,
Guido.

Luckie 14. Sep 2008 02:19

Re: Record zurücksetzen (löschen)
 
Zitat:

Zitat von Guido Eisenbeis
Delphi-Quellcode:
// Beispiel:

type
  TMyRecord = record
    Test_1:          string;
    Test_2:          string;
    Test_3:          string;
    Integer_1:       integer;
    Integer_2:       integer;
  end;

 ...

 MyRecord: TMyRecord;
Hi,

da ich bei meiner Suche nichts gefunden habe, ahne ich, dass ich da selbst Hand angelegt muss. Aber dennoch die Frage: Gibt es eine Delphi-Funktion um ein Record zu löschen? Also sowas wie MyRecord := nil? :gruebel:

Guido.

Nein gibt es nicht. Warum willst du ihn denn löschen? Oder besser noch, sag uns, was du eigentlich vor hast.
Zitat:

Zitat von Guido Eisenbeis
Warum schrummpelt den die Forum-Fensterdarstellung bei mir so zusammen?

Das Forum hat sich wohl verschluckt. Ich habe den Beitrag neu abgeschickt, jetzt stimmt wieder alles.

toms 14. Sep 2008 07:44

Re: Record zurücksetzen (löschen)
 
Hallo, du könntest Finalize + FillChar verwenden, um deinen Record zu "löschen":

Delphi-Quellcode:
 
 Finalize(MyRecord);
 FillChar(MyRecord, SizeOf(MyRecord), 0);
Oder du verwendest einen "BlankRecord". Vorteil: Du bestimmst selber die Werte, welche die Felder erhalten sollen.

Delphi-Quellcode:
const
  MyBlankRecord : TMyRecord = (Test_1: ''; Test_2: ''; Test_3: ''; Integer_1: 0; Integer_2: 0);
begin
  MyRecord := MyBlankRecord;
end;

sirius 14. Sep 2008 08:04

Re: Record zurücksetzen (löschen)
 
Was heißt den löschen?

MSSSSM 14. Sep 2008 08:19

Re: Record zurücksetzen (löschen)
 
Alle Felder leeren wahrscheinlich.

Hawkeye219 14. Sep 2008 09:20

Re: Record zurücksetzen (löschen)
 
Man könnte den ersten Vorschlag von toms sogar noch etwas erweitern:

Delphi-Quellcode:
type
  TMyRecord = record
    Test_1    : string;
    Test_2    : string;
    Test_3    : string;
    Integer_1 : Integer;
    Integer_2 : Integer;
    procedure Clear;
  end;

procedure TMyRecord.Clear;
begin
  Finalize (Self);
  FillChar (Self, SizeOf(Self), 0);
end;

// Anwendung:

var
  MyRecord : TMyRecord;
begin
  MyRecord.Clear;
end;
In der Methode Clear müssen vor dem abschließenden FillChar-Befehl alle (dynamischen) Daten im Record freigegeben werden. Finalize selbst berücksichtigt nur die referenzgezählten Daten. Speicherbereiche, die mit New o.ä. angelegt wurden, sowie Objekte, die durch Aufruf eines Konstruktors erzeugt wurden, muss man also auch manuell freigeben.

Gruß Hawkeye

Luckie 14. Sep 2008 11:33

Re: Record zurücksetzen (löschen)
 
Mist an FillChar habe ich nicht gedacht.

SubData 14. Sep 2008 12:21

Re: Record zurücksetzen (löschen)
 
Wenn er mit FillChar das Record löscht, dann werden aber die "Strings" da drin nicht wirklich überschrieben, sondern nur die Pointer, oder seh ich das jetzt falsch?

Hansa 14. Sep 2008 12:27

Re: Record zurücksetzen (löschen)
 
Zitat:

Zitat von SubData
..dann werden aber die "Strings" da drin nicht wirklich überschrieben, sondern nur die Pointer, oder seh ich das jetzt falsch?

jo, ist falsch.

Neutral General 14. Sep 2008 12:28

Re: Record zurücksetzen (löschen)
 
Mh nee.. Ich glaube das siehst du richtig. Jetzt wo du's sagst... Muss man halt wirklich ne Record-Methode (seltsame Teile wie ich finde..) schreiben

Zitat:

Zitat von Hansa
Zitat:

Zitat von SubData
..dann werden aber die "Strings" da drin nicht wirklich überschrieben, sondern nur die Pointer, oder seh ich das jetzt falsch?

jo, ist falsch.

Ne ist richtig :stupid:

Guido Eisenbeis 14. Sep 2008 12:29

Re: Record zurücksetzen (löschen)
 
@Michael:
Danke für das "Entschrummpeln" der Forumsansicht! :thumb:


Zitat:

Zitat von Luckie
Oder besser noch, sag uns, was du eigentlich vor hast.

Zitat:

Zitat von sirius
Was heißt den löschen?

Record löschen, zurücksetzen, oder wie Marius schrieb "Alle Felder leeren", also alle Werte des Records auf einen Anfangswert setzen. Z. B. Strings auf '' (leer), Integer auf 0, ...

Was ich vorhabe:

Zum einen will ich hierbei meinen Delphi-Horizont erweitern. Bisher habe ich bei Records eine Routine geschrieben, in der alle Felder auf einen definierten Wert gesetzt wurden. Beispiel:

Delphi-Quellcode:

Type
  TMyRecord = record
    Test_1    : string;
    Test_2    : string;
    Integer_1 : Integer;
    Integer_2 : Integer;
  end;


function PrepareMsg(AMyRecord: TMyRecord): string;
begin
  Result :=
    'Test_1:   ' + AMyRecord.Test_1 + #13#10+
    'Test_2:   ' + AMyRecord.Test_2 + #13#10+
    'Integer_1:   ' + IntToStr(AMyRecord.Integer_1) + #13#10+
    'Integer_2:   ' + IntToStr(AMyRecord.Integer_2);
end;


procedure ResetMyRecord(var AMyRecord: TMyRecord);
begin
  AMyRecord.Test_1 := '';
  AMyRecord.Test_2 := '';
  AMyRecord.Integer_1 := 0;
  AMyRecord.Integer_2 := 0;
end;


procedure SetTestValues(var AMyRecord: TMyRecord);
begin
  AMyRecord.Test_1 := 'Hallo ';
  AMyRecord.Test_2 := 'Welt!';
  AMyRecord.Integer_1 := 9;
  AMyRecord.Integer_2 := 2008;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  MyRecord: TMyRecord;
begin
  // undefinierte AnfangsWerte (beim ersten Test erscheinen hier Zufallswerte)
  ShowMessage(PrepareMsg(MyRecord));

  // BeispielWerte zuweisen
  SetTestValues(MyRecord);
  ShowMessage(PrepareMsg(MyRecord));

  // mit "händischer" Lösung auf definierte AnfangsWerte setzen
  ResetMyRecord(MyRecord);
  ShowMessage(PrepareMsg(MyRecord));

  // BeispielWerte zuweisen
  SetTestValues(MyRecord);
  ShowMessage(PrepareMsg(MyRecord));

  // "FillChar"-Lösung
  Finalize(MyRecord);
  FillChar(MyRecord, SizeOf(MyRecord), 0);
  ShowMessage(PrepareMsg(MyRecord));
end;
Nun will ich zum Einen wissen, ob es da eine einfachere Möglichkeiten gibt, um meinen Code kürzer und übersichtlicher zu halten.
Zum Anderen hat die obige "händische" Lösung zwar den Vorteil, dass man selbst definierte Werte erhält, aber den Nachteil, dass das bei umfangreicheren Records schnell recht aufwendig wird. Hinzu kommt, dass in meinem konkretten Fall (Verknüpfungen auslesen) mein Record auch noch einen weiteren Record enthält. Da ist dann die Frage, wie weit die händische Lösung sinnvoll ist.

Delphi-Quellcode:
type
  TMyRecord = record
    Test_1    : string;
    Test_2    : string;
    Integer_1 : Integer;
    Integer_2 : Integer;
    FindData: TWIN32FINDDATA; // <-- weiterer Record in meinem Record
  end;

@toms

Die "MyBlankRecord"-Lösung entspricht in meiner Auffassung der "händischen" Lösung, ist hier also nicht gewollt.

Die "FillChar"-Lösung erscheint mir eher als eine Lösung in meinem Sinne. Gewünscht ist eine Lösung mit kurzem Code, die schon-vorhandene Delphi Routinen benutzt. Und das wäre hierbei der Fall. Und es schein sogar recht elegant zu sein.

OK, nach ersten Tests (siehe Komplett-Code oben) scheint die "FillChar"-Möglichkeit tatsächlich die gewünschte "elegange" Lösung zu sein. Ich werde nun noch Test mit dem zusätzlichen Record in meinem Record (FindDate: TWIN32FINDDATA) durchführen.


@Ronny
Meines Wissens nach werden mit FillChar auch die Strings auf "0" gesetzt (komplett mit Nullen gefüllt, also sozusagen Null-terminiert). Das entspricht einem leeren String und ist das gewünschte Ziel.

Mal sehen, was die anderen sagen. :-D

Guido.

Neutral General 14. Sep 2008 12:34

Re: Record zurücksetzen (löschen)
 
Hi,

Ein "Beweis", dass FillChar nicht funktioniert:
Delphi-Quellcode:
type
  TBeweis = packed record
    EinString: String;
    Zahl: Integer;
  end;

var Beweis: TBeweis;
    p: Pointer;
begin
  Beweis.EinString:= 'Test';
  p := @Beweis.EinString[1];
  FillChar(Beweis,SizeOf(TBeweis),0);
  ShowMessage(PChar(p));
end;
Dürfte dann übrigens ein schönes Speicherleck geben ;) (Außer der Memory-Manager räumt das trotzdem auf)
Wie SubData schon gesagt hat: Der Pointer zu dem eigentlichen String wird auf nil gesetzt. Aber der String selbst schwirrt noch im Speicher rum. Ist nur nichtmehr erreichbar, falls man den Pointer nicht vorher gesichert hat ;)

Hansa 14. Sep 2008 12:46

Re: Record zurücksetzen (löschen)
 
Liste der Anhänge anzeigen (Anzahl: 1)
Du beweist, dass man jedes noch so simple Problemchen derart verunstalten kann, dass es eventuell nicht mal richtig funktioniert. :mrgreen:

Delphi-Quellcode:
  MyRecord.nr := 1;
  MyRecord.name := 'XYZ';
  memo2.Lines.Add(IntToStr(MyRecord.nr));
  memo2.Lines.Add('*'+MyRecord.name+'*');
  memo2.Lines.Add('');
  FillChar (MyRecord,SizeOf (MyRecord),0);
  memo2.Lines.Add(IntToStr(MyRecord.nr));
  memo2.Lines.Add('*'+MyRecord.name+'*');
Das ergibt das im Anhang.

SubData 14. Sep 2008 12:47

Re: Record zurücksetzen (löschen)
 
Jap, so in etwa dachte ich mir das.
Finalize scheint aber auch nicht zu funktionieren.

Jedenfalls nicht, wenn das Record eine ThreadVar ist.
Zumindest meldet FastMM danach noch Speicherlecks.


Edit:

Zitat:

Zitat von Hansa
Du beweist, dass man jedes noch so simple Problemchen derart verunstalten kann, dass es eventuell nicht mal richtig funktioniert. :mrgreen:

Delphi-Quellcode:
  MyRecord.nr := 1;
  MyRecord.name := 'XYZ';
  memo2.Lines.Add(IntToStr(MyRecord.nr));
  memo2.Lines.Add('*'+MyRecord.name+'*');
  memo2.Lines.Add('');
  FillChar (MyRecord,SizeOf (MyRecord),0);
  memo2.Lines.Add(IntToStr(MyRecord.nr));
  memo2.Lines.Add('*'+MyRecord.name+'*');
Das ergibt das im Anhang.

Damit beweist du nur, dass der Pointer auf den eigentlichen String nicht mehr existiert.
Ob der String damit aber wirklich freigegeben wurde, wird daraus nicht deutlich.

SubData 14. Sep 2008 12:49

Re: Record zurücksetzen (löschen)
 
Edit: Kann weg...

Neutral General 14. Sep 2008 12:50

Re: Record zurücksetzen (löschen)
 
Natürlich steht dann in MyRecord.Name nichts mehr. Weil der String "genilt" wurde. Aber der String selbst liegt immernoch im Speicher rum.

SubData 14. Sep 2008 12:51

Re: Record zurücksetzen (löschen)
 
Und ich wette FastMM würde rumnörgeln ;-)

Edit: Michael: Magste das mal mit FastMM testen?

Hansa 14. Sep 2008 12:54

Re: Record zurücksetzen (löschen)
 
Zitat:

Zitat von Neutral General
..Aber der String selbst liegt immernoch im Speicher rum.

Da liegt noch viel mehr rum. In diesem speziellen Fall gehe ich allerdings davon aus, dass tatsächlich die Variable anderen Wert bekommt und nicht extra neu angelegt wird. Bei einem Record handelt es sich nunmal NICHT um Pointer etc.

SubData 14. Sep 2008 13:06

Re: Record zurücksetzen (löschen)
 
Zitat:

Zitat von Hansa
Bei einem Record handelt es sich nunmal NICHT um Pointer etc.

Bei Strings im Record schon (Solange es keine ShortStrings) sind.

alzaimar 14. Sep 2008 13:13

Re: Record zurücksetzen (löschen)
 
FastMM meldet jedenfalls nichts.

Neutral General 14. Sep 2008 13:13

Re: Record zurücksetzen (löschen)
 
Also es sieht laut FastMM4 so aus:

Delphi-Quellcode:
type
  TBeweis = packed record
    EinString: String;
    Zahl: Integer;
  end;

procedure TForm1.Button1Click(Sender: TObject);
var Beweis: TBeweis;
    p: Pointer;
begin
  Beweis.EinString:= 'Test';
  p := @Beweis.EinString[1];
  FillChar(Beweis,SizeOf(TBeweis),0);
  ShowMessage(PChar(p));
end;
erzeugt KEIN MemoryLeak. Der MemoryManager schafft es wohl trotzdem den String nach der Methode mit dem Record freizugeben.

Anders siehts bei globalen Variablen oder Klassenvariablen aus. Da hinterlässt dieser Code ein MemoryLeak. Aber auch das kann verhindert werden:

Delphi-Quellcode:
Finalize(Beweis);
Diese Zeile vor dem FillChar lässt das MemoryLeak verschwinden.

Delphi-Quellcode:

// Globale- oder Klassenvariable
var Beweis: TBeweis;

procedure TForm1.Button1Click(Sender: TObject);
var
    p: Pointer;
begin
  Beweis.EinString:= 'Test';
  p := @Beweis.EinString[1];
  Finalize(Beweis); // <--- 
  FillChar(Beweis,SizeOf(TBeweis),0);
  ShowMessage(PChar(p));
end;
@Hansa:

Ich weiß, dass es sich bei Records nicht um Pointer handelt. Aber das hat nichts damit zu tun. Fakt ist, dass mit FillChar nur der Pointer zu dem eigentlichen String überschrieben wird. Der String selbst liegt weiterhin im Speicher! Daran ist nichts zu rütteln.

Popov 14. Sep 2008 13:13

Re: Record zurücksetzen (löschen)
 
Zitat:

Zitat von Guido Eisenbeis
da ich bei meiner Suche nichts gefunden habe, ahne ich, dass ich da selbst Hand angelegt muss. Aber dennoch die Frage: Gibt es eine Delphi-Funktion um ein Record zu löschen? Also sowas wie MyRecord := nil? :gruebel:

Alle Tipps schön und gut, man muß sie sich aber immer merken und bevor man dann stundenlang überlegt wie das war, ein mal machen, immer wieder nutzen können ;)

Delphi-Quellcode:
procedure MyRecordClear;
begin
  with MyRecord do
  begin
    Test_1 := '';
    Test_2 := '';
    Test_3 := '';
    Integer_1 := 0;
    Integer_2 := 0;
  end;
end;
Man sollte sich das Leben einfach machen.

Guido Eisenbeis 14. Sep 2008 13:19

Re: Record zurücksetzen (löschen)
 
Damit keine Missverständnisse auftreten:

Der (die) String(s) sollen KEINESFALLS freigegeben werden! Im Gegenteil: Sie werden ja in meinem Programm benötigt!

Sie sollen lediglich auf leer (, Integer auf 0, ...) gesetzt werden! (Speicherplatz soll beibehalten weren.)


Der "Beweis" von Neutral General beweist nur, dass der Bereich im Speicher noch die Werte beinhaltet. Das ist ja auch in Ordnung. Ich gehe davon aus, dass FillChar nur die Länge(nangabe) des Strings auf 0 setzt. Das entspräche einem leeren String = gewünschtes Ergebnis.

Speicherleck kann ich mir nicht vorstellen, da der Platz ja reserviert bleiben soll, bis die Record-Variable am Programm-Ende freigegeben wird.

Guido.

SubData 14. Sep 2008 13:19

Re: Record zurücksetzen (löschen)
 
@Michael: Kannst du das mal mit einer globalen ThreadVar Variable testen?
Einmal mit Finalize und einmal ohne.

Edit:
@Guido: Das siehst du leider ein wenig falsch.
Damit wird der Pointer auf den eigentlichen String überschrieben.
Das bedeutet aber nicht, dass bei einer neuen Zuweisung der String wieder an der selben Stelle im Speicher liegt.
Dementsprechend wird auch nicht die Längenangabe vom String auf 0 gesetzt, sondern der Pointer zum String.

Guido Eisenbeis 14. Sep 2008 13:22

Re: Record zurücksetzen (löschen)
 
Zitat:

Zitat von Popov
Alle Tipps schön und gut, man muß sie sich aber immer merken und bevor man dann stundenlang überlegt wie das war, ein mal machen, immer wieder nutzen können ;)

Delphi-Quellcode:
procedure MyRecordClear;
begin
  with MyRecord do
  begin
    Test_1 := '';
    Test_2 := '';
    Test_3 := '';
    Integer_1 := 0;
    Integer_2 := 0;
  end;
end;

Was aber machst du, wenn, wie oben beschrieben, dein Record noch andere Records enthält (z. B. FindData: TWIN32FINDDATA) und die dann wieder weitere Records enthalten, die dann ... ?

Guido.

Neutral General 14. Sep 2008 13:23

Re: Record zurücksetzen (löschen)
 
Zitat:

Zitat von SubData
@Michael: Kannst du das mal mit einer globalen ThreadVar Variable testen?
Einmal mit Finalize und einmal ohne.

Edit:
@Guido: Das siehst du leider ein wenig falsch.
Damit wird der Pointer auf den eigentlichen String überschrieben.
Das bedeutet aber nicht, dass bei einer neuen Zuweisung der String wieder an der selben Stelle im Speicher liegt.
Dementsprechend wird auch nicht die Längenangabe vom String auf 0 gesetzt, sondern der Pointer zum String.

Gleiches Ergebnis wie mit normalen globalen Variablen und Klassenvariablen. Ohne Finalize gibtsn MemoryLeak. Mit gibts keins.

@Guido Eisenbeis:

FillChar bewirkt schon, dass die Strings leer sind (leer darum, weil der Pointer zum String jetzt irgendwohin zeigt, wo kein String liegen wird). Aber wenn du das machst, musst/solltest du vorher Finalize(Record) aufrufen. Ansonsten gibt es wie gesagt ein MemoryLeak bei globalen (Thread) Variablen und Klassenvariablen.

SubData 14. Sep 2008 13:26

Re: Record zurücksetzen (löschen)
 
Danke!

Ich hab nämlich mal die böse Erfahrung gemacht, dass ich ThreadVar Records am Ende des Threads wieder explizit löschen muss, da sonst die Strings im Record MemoryLeaks verursachen.
Den Fehler muss man erstmal finden :roll:

Popov 14. Sep 2008 13:26

Re: Record zurücksetzen (löschen)
 
Zitat:

Zitat von Guido Eisenbeis
Was aber machst du, wenn, wie oben beschrieben, dein Record noch andere Records enthält?

Wird nur etwas länger.

Apollonius 14. Sep 2008 13:29

Re: Record zurücksetzen (löschen)
 
@SubData: Die Hilfe hilft:
Zitat:

Dynamic variables that are ordinarily managed by the compiler (long strings, wide strings, dynamic arrays, variants, and interfaces) can be declared with threadvar, but the compiler does not automatically free the heap-allocated memory created by each thread of execution. If you use these data types in thread variables, it is your responsibility to dispose of their memory from within the thread, before the thread terminates.

SubData 14. Sep 2008 13:32

Re: Record zurücksetzen (löschen)
 
Weiß ich, hab ich danach auch gelesen.

Neutral General 14. Sep 2008 13:33

Re: Record zurücksetzen (löschen)
 
Zitat:

Zitat von Popov
Zitat:

Zitat von Guido Eisenbeis
Was aber machst du, wenn, wie oben beschrieben, dein Record noch andere Records enthält?

Wird nur etwas länger.

Delphi-Quellcode:
Finalize(Record);
FillChar(Record,SizeOf(TRecord),0);
Ist die ultimative Lösung :mrgreen: Damit werden auch Subrecords aufgeräumt. Habs ausprobiert.

Guido Eisenbeis 14. Sep 2008 13:37

Re: Record zurücksetzen (löschen)
 
Zitat:

Zitat von Popov
Wird nur etwas länger.

Optimist *smile* :-D


@Michael + Ronny

Danke für die Infos! Also seid ihr der Meinung, dass mit Finalize + FillChar sauber gearbeitet wird?

Guido.

SubData 14. Sep 2008 13:39

Re: Record zurücksetzen (löschen)
 
Ja :)

Und bei der Gelegenheit: FastMM
Hilft dabei Speicherlecks zu finden (Und optimiert auch gleich die Anwendung)

Guido Eisenbeis 14. Sep 2008 13:39

Re: Record zurücksetzen (löschen)
 
Zitat:

Zitat von Neutral General
Delphi-Quellcode:
Finalize(Record);
FillChar(Record,SizeOf(TRecord),0);
Ist die ultimative Lösung :mrgreen: Damit werden auch Subrecords aufgeräumt. Habs ausprobiert.

Danke! Ich wollte diesbezüglich auch gerade Tests durchführen. Hast du mir erspart! *freu*

Guido.

Neutral General 14. Sep 2008 13:57

Re: Record zurücksetzen (löschen)
 
Hi,

In den neueren Delphiversionen kann mans noch in eine Methode packen. Ist dann nachher etwas bequemer:

Delphi-Quellcode:
type
  TRecord = record
    // ...
    procedure Clear;
  end;

procedure TRecord.Clear;
begin
  Finalize(Self);
  FillChar(Self,SizeOf(Self),0);
end;
Edit: Schade, dass es keine Vererbung bei Records gibt, sonst hätte man da was TObject-mäßiges bauen können :stupid:

Popov 14. Sep 2008 14:16

Re: Record zurücksetzen (löschen)
 
Zitat:

Zitat von Neutral General
Delphi-Quellcode:
Finalize(Record);
FillChar(Record,SizeOf(TRecord),0);

Also funktionieren tut es ja, aber ist das auch sauber? Also ich hab mich schon lange nicht mehr mit dem inneren Aufbau der Variablen beschäftigt, aber wie lang ist ein String im Speicher? Also "Hallo" dürfte 5 Zeichen lang sein und ist es nicht so, daß die Länge 5 auch vermerkt wird? Wenn ich sie nun auf 0 stelle, kürze ich die zwar, hinterlasse aber, zwar genullten Bereich, aber immerhin, im Speicher.

Wie gesagt, interessiert mich nur etwas. Kann auch falsch sein.

Popov 14. Sep 2008 14:17

Re: Record zurücksetzen (löschen)
 
Zitat:

Zitat von Neutral General
Edit: Schade, dass es keine Vererbung bei Records gibt, sonst hätte man da was TObject-mäßiges bauen können :stupid:

Wieso nicht gleich eine Klasse?

Neutral General 14. Sep 2008 14:31

Re: Record zurücksetzen (löschen)
 
Zitat:

Zitat von Popov
Zitat:

Zitat von Neutral General
Delphi-Quellcode:
Finalize(Record);
FillChar(Record,SizeOf(TRecord),0);

Also funktionieren tut es ja, aber ist das auch sauber? Also ich hab mich schon lange nicht mehr mit dem inneren Aufbau der Variablen beschäftigt, aber wie lang ist ein String im Speicher? Also "Hallo" dürfte 5 Zeichen lang sein und ist es nicht so, daß die Länge 5 auch vermerkt wird? Wenn ich sie nun auf 0 stelle, kürze ich die zwar, hinterlasse aber, zwar genullten Bereich, aber immerhin, im Speicher.

Wie gesagt, interessiert mich nur etwas. Kann auch falsch sein.

Ich gehe einfach mal davon aus, dass Finalize das übernimmt. Wie gesagt. Es gibt ohne Finalize ein MemoryLeak, mit nicht.

Edit: Hab mal was ausprobiert:
Delphi-Quellcode:
// EinString = 'Test';
procedure TRecord.Clear;
begin
  ShowMessage(EinString); // 'Test'
  Finalize(Self);
  ShowMessage(EinString); // ''
  FillChar(Self,SizeOf(Self),0);
end;
Damit dürften wohl alle Zweifel und Unklarheiten aus der Welt geschafft sein :)

Zitat:

Zitat von Popov
Zitat:

Zitat von Neutral General
Edit: Schade, dass es keine Vererbung bei Records gibt, sonst hätte man da was TObject-mäßiges bauen können :stupid:

Wieso nicht gleich eine Klasse?

Frag mich das nicht. Ich benutze seit einiger Zeit keine Records mehr ;) Aber würde halt Spaß machen son TRecord zu bauen :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:00 Uhr.
Seite 1 von 3  1 23      

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