![]() |
Spring4D Nullable<T> fHasValue: string;
Bei meiner Suche nach Memory-Leaks bin ich in unit "Spring.pas" auf diesen Code gestossen:
Delphi-Quellcode:
Kann mir jemand erklären warum man hier für fHasValue einen string nimmt und nicht ein Boolean? Zugewiesen wird dem string nur 'True' und ''.
Nullable<T> = record
private fValue: T; fHasValue: string; .. |
AW: Spring4D Nullable<T> fHasValue: string;
Weil der String automatisch initialisiert wird und ein Boolean ohne vorherrige Zuweisung sonst einen Zufallswert haben kann.
(würde ich mir vorstellen, da ich bei meinen eigenen Komponenten leider auch so einen "Scheiß" bauen muß, da Embarcadero meine Vorschläge nötige Funktionalitäten mit wenigen Zeilen Qellcode nachzurüsten, einfach ignriert hat, obwohl ich denen sogar schon den fertigen Code geliefert hatte) |
AW: Spring4D Nullable<T> fHasValue: string;
Ah ja Danke. Das ist eine plausible Erklärung.
Leider benötigt dieser string ja nicht gerade wenig Speicher (min 2x4=8 bei 32-Bit). Bei einem Nullable<Boolean> braucht man dann statt einem Byte dann 9. Und leider bleibt beim Memory-Leak das ich untersuche immer dieser String übrig. Ich muss das noch genauer untersuchen, ich meine eine Exception ist beteiligt. |
AW: Spring4D Nullable<T> fHasValue: string;
Ja, mit ein paar kleinen Änderungen im Delphi würde der Typ dann für NullableBoolean nur 2 Byte benötigen. (oder gar 1 Byte, wenn man z.B. nur 1 bzw. -1 für True annimmt, bzw. wenn nur das erste Bit werthaltig ist)
Falls du sicherstellen kannst, dass der die Variable immer initialisiert wird, könntest du den Typen entsprechend anpassen. Oder ein Treestate-Boolean nutzen, aber dann mußt du "true" wirklich mit = True prüfen.
Delphi-Quellcode:
Wobei du hier den Speicher selbst initialisieren mußt, da automatische Initialisierungen immer nur 0 verwenden, was natürlich False wäre.
const NullBool = Boolean($55);
B := NullBool; if not B then FALSCH if B = False then FALSCH; if B = True then WAHR; if B = NullBool then LEER; if B then WAHR_oder_LEER; In einem Record, mit paar Implizit-Casts könne man hier noch False und Null im Record umdrehen, bzw. drinnen einen ENUM (Null,True,False) benutzen. Ein MemoryLeak sollte aber beim Nullable<T> nicht bleiben. Wo/wie benutzt du denn diesen Typen? Wenn man das NULL im Datentypen selbst speichern könnte, bzw. wenn es möglich ist dort einen Wert im Wertebereich als NULL zu definieren, dann ändert sich am eigentlichen Speicherverbrauch natürlich nichts. Aber für soeinen generischen Typen, der alles aufnehmen kann, ist sowas natürlich garnicht oder nicht "einfach" umzusetzen. Siehe dazu die Fließkommatypen (natürlich abgesehn von Currency) ansieht, dann sind da ein paar Bitkombinationen frei, die für sowas wie NAN, Inf und NegInf verwendet werden konnten. |
AW: Spring4D Nullable<T> fHasValue: string;
Zitat:
|
AW: Spring4D Nullable<T> fHasValue: string;
Zitat:
![]() Ich habe das für meine TNullableXxxx-Typen so implementiert und es funktioniert problemlos. Edit: Wobei: Eigentlich braucht der String auch nur 4 Bytes (oder 8 Bytes bei 64 Bit), wenn man immer denselben zuweist, denn dann ist das nur noch der Pointer auf den String-Descriptor. Der String selbst (und sein Descriptor) existiert nur noch ein einziges Mal. Ohne die Implementation in Spring4G zu gesehen zu haben, könnte ich mir vorstellen, dass das dort genauso implementiert ist. |
AW: Spring4D Nullable<T> fHasValue: string;
Gut, wenn das Interface hier nur als Boolean (False=leer und True=einWert) verwendet wird, dann ist der String einfacher, denn wenn als String nur eine Konstante verwendet wird, dann braucht der auch keinen Speicher und man muß sich das DummyInterface nicht basteln
|
AW: Spring4D Nullable<T> fHasValue: string;
Werden Felder nicht automatisch initialisiert?
Mir war doch so, und die OH sagt sazu: ![]() Trifft ja der Beschreibung nach auch so auf FHasValue zu. Habe ehrlich gesagt auch noch nie gehört oder gesehen, dass das nicht der Fall sein soll (abgesehen von lokalen Variablen bei Unterfunktionen, aber da funktioniert die Initialisierung ja eh scheinbar nie richtig). |
AW: Spring4D Nullable<T> fHasValue: string;
Es ist aber kein "object" sondern ein record
Zitat:
Am Besten wäre EMB, würde das native unterstützen. |
AW: Spring4D Nullable<T> fHasValue: string;
Zitat:
Global oder als Feld in einem Objekt, wo der Speicher initialisiert wird, oder als lokale Variable in einer Funktion/Prodedur/Methode, wo das eben nicht passiert. Wobei Strings, dynamische Arrays und Interfaces "immer" initialisiert werden. (außer wenn in Pointern, wo jemand alles falsch macht und die Speicherverwaltung verhunzt hat) automatisch freigegeben wird der String auch immer automatisch. (weswegen er auch vorher initialisiert werden musste, damit die Automatik funktioniert) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:45 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz