Wie man richtig frei Datensätze, die enthalten verschiedene Typen in Delphi auf einmal?
type
TSomeRecord = Record
field1: integer;
field2: string;
field3: boolean;
End;
var
SomeRecord: TSomeRecord;
SomeRecAr: array of TSomeRecord;
Dies ist das einfachste Beispiel, was ich habe und da ich wiederverwenden möchten SomeRecord
(mit bestimmte Felder leer bleiben, ohne zu befreien, alles einige Felder übertragen werden, wenn ich bin wiederverwenden SomeRecord
die offensichtlich unerwünschten) ich bin auf der Suche nach einem Weg, Sie zu befreien, alle Felder auf einmal. Ich habe angefangen mit string[255]
und verwendet ZeroMemory()
das war in Ordnung, bis er anfing undicht zu Erinnerung, das war nur, weil ich umgestiegen auf string
. Mir fehlt noch das wissen, warum, aber es scheint mit, dass es dynamisch ist. Ich bin mit dynamischen arrays, also gehe ich davon aus, dass der Versuch ZeroMemory()
auf etwas Dynamik würde führen zu Undichtigkeiten. Einen Tag verschwendet, herauszufinden, dass heraus. Ich denke, dass ich dies Problem gelöst durch die Verwendung Finalize()
auf SomeRecord
oder SomeRecAr
vor ZeroMemory()
aber ich bin mir nicht sicher, ob das der richtige Ansatz oder einfach nur mich dumm.
Also die Frage ist: wie frei alles auf einmal? zu ein paar einzelnen Verfahren existieren für diese, ich bin mir nicht bewusst?
Auf einer anderen Anmerkung, alternativ wäre ich für Vorschläge offen, wie implementiert man diese Sätze anders zu beginnen mit, so brauche ich mich nicht zu komplizierte versuche zu befreien Zeug. Ich sah in die Erstellung von Datensätzen mit New()
und dann, es loszuwerden Dispose()
aber ich habe keine Ahnung, was es bedeutet, wenn eine variable nach einem Aufruf von Dispose()
nicht definiert ist, wird statt der null. Außerdem, ich weiß nicht, was ist der Unterschied zwischen einer Variablen eines bestimmten Typs (SomeRecord: TSomeRecord
) im Vergleich zu einer Variablen weist auf einen Typ (SomeRecord: ^TSomeRecord
). Ich bin auf der Suche in den oben genannten Probleme im moment, es sei denn, jemand kann es erklären schnell, kann es einige Zeit dauern.
InformationsquelleAutor der Frage Raith | 2012-06-16
Du musst angemeldet sein, um einen Kommentar abzugeben.
Vorausgesetzt, Sie haben eine Delphi-version, unterstützt die Implementierung von Methoden auf einen Datensatz, den Sie löschen konnte diesen Eintrag:
Wenn Ihr compiler nicht unterstützt
Default
dann können Sie das gleiche tun ganz einfach so:Du vielleicht lieber vermeiden mutierend einen Werttyp in einer Methode. In dem Fall erstellen Sie eine Funktion zurückgibt, die einen leeren Eintrag Wert, und verwenden Sie es mit dem Zuweisungsoperator:
Als ein beiseite, ich finde keine Dokumentation Referenzhandbuch für
Default(TypeIdentifier)
. Weiß jemand, wo es gefunden werden kann?Als für den zweiten Teil Ihrer Frage, ich sehe keinen Grund, nicht weiter zu verwenden Datensätze, und die Zuweisung von Sie Sie mit dynamischen arrays. Versuch, um die Lebensdauer zu verwalten sich selbst, ist viel mehr fehleranfällig.
InformationsquelleAutor der Antwort David Heffernan
Nicht machen, denkt zu kompliziert!
Zuweisung einer "default" -
record
ist nur ein Verlust der CPU-Leistung und Speicher.Wenn ein
record
deklariert ist innerhalb einerTClass
es ist gefüllt mit null, also initialisiert. Wenn Sie zugeordnet sind, auf Stapel, nur Verweis gezählt werden Variablen initialisiert werden: andere Art von Variablen (wie integer oder double oder Boolean oder enumerations) werden in einen zufälligen Zustand (vermutlich nicht null). Wenn es dem heap zugeordnet werden,getmem
wird nicht initialisiert nichts,allocmem
füllt alle Inhalte mit null, undnew
initialisieren wird nur die Referenz-gezählten Elemente (wie auf der stack-Initialisierung): in allen Fällen sollten Sie entwederdispose
entwederfinalize+freemem
um die Freigabe der auf dem heap allokiertrecord
.Also etwa genau Ihre Frage, Ihre eigene Annahme richtig war: zurücksetzen eines Datensatzes Inhalt nach verwenden, benutzen Sie nie "
fillchar
" (oder "zeromemory
") ohne eine Vorherige "finalize
". Hier ist der richtige und Schnellste Weg:Wieder, es wird schneller sein als die Zuordnung eines default-Datensatz. Und in jedem Fall, wenn Sie
Finalize
sogar mehrfach, es wird nicht Leck Speicher - 100% Geld-zurück-Garantie!Edit: Nach einem Blick auf den code generiert
aRecord := default(TRecordType)
ist, wird der code gut optimiert ist: es ist in der Tat einFinalize
+ Bündel vonstosd
zu emulierenFillChar
. Selbst wenn also die syntax ist eine Kopie /Ausgangsbelegung (:=
), ist es nicht implementiert ist als eine Kopie /Belegung. Mein Fehler hier.Aber ich weiß noch nicht, wie die Tatsache, dass ein
:=
verwendet werden, wo Embarcadero sollte besser genutzt werden, einrecord
Methode wieaRecord.Clear
wie syntax, wie DelphiWebScript dynamischen arrays. In der Tat, diese:=
syntax ist die gleiche verwendet von C#. Klingt wie wenn Embacardero nur imitiert die C# - syntax überall, ohne herauszufinden, dass das ist seltsam. Was ist der Punkt, wenn Delphi ist nur ein Mitläufer, und nicht umzusetzen, denkt sich "seinen Weg"? Die Menschen werden immer lieber das original von C# zu seinen Vorfahren (Delphi hat den gleichen Vater).InformationsquelleAutor der Antwort Arnaud Bouchez
Die einfachste Lösung denke ich wird sein:
Aber für all die übrigen Teile in Ihrer Frage nehmen Sie diese Definitionen:
Dann hier einige mehrere Beispiele, wie man mit Ihnen arbeiten:
Auswählen und/oder kombinieren, wie Sie möchten.
InformationsquelleAutor der Antwort NGLN
Mit
SomeRecord: TSomeRecord
SomeRecord
wird eine Instanz/variable vom TypTSomeRecord
. MitSomeRecord: ^TSomeRecord
SomeRecord
wird ein Zeiger auf eine Instanz oder variable vom TypTSomeRecord
. Im letzten FallSomeRecord
wird ein typisierter pointer. Wenn Ihre Anwendung die übertragung eine Menge von Daten zwischen Programmen oder die Interaktion mit externen API, typisierte Zeiger empfohlen.new()
unddispose()
sind nur mit typisierten Zeigern. Mit typisierten Zeiger der compiler nicht kontrollieren/Kenntnis der memory-Anwendung mit dieser Art von vars. Es ist bis zu Ihnen, um kostenlos den Speicher durch typisierte Zeiger.In der anderen hand, wenn Sie einen normalen Variablen, je nach der Verwendung von und der Deklaration, kann der compiler Speicher frei von Ihnen verwendet werden, wenn Sie der Auffassung sind Sie nicht mehr nötig. Zum Beispiel:
Im obigen Beispiel die variable
NativeVariable
ist nur innerhalb derSomeStaff
- Funktion, damit der compiler automatisch freigeben, wenn die Funktion endet. Diese appy für fast die meisten systemeigenen Variablen, einschließlich arrays und records "Felder". Objekte anders behandelt werden, aber das ist für einen anderen post.InformationsquelleAutor der Antwort Christopher Ramírez