![]() |
Speicherbereinigung von Strings
Morgen.
Ich habe ein kleines Problem. Ich speichere einen Pointer auf einen String in einer Datenstruktur. Da stellt sich natürlich die Frage: Wann gibt der Speichermanager den String frei? Kann es sein, dass von dem String nichts mehr übrig ist, wenn ich den Pointer wieder aus der Struktur hole? Muss ich den String in eine Wrapper-Klasse verpacken? |
Re: Speicherbereinigung von Strings
Ohne genau probiert zu haben, denke ich, das der String freigegeben wird, wenn der Kontext verlassen wird. Seine Adresse ist dann imho nicht mehr gültig. Zeig doch mal Code, würde mich nämlich auch interessieren.
|
Re: Speicherbereinigung von Strings
Ich bin noch in der Planungsphase. Im Prinzip wäre das aber so, dass ich sowas bräuchte wie eine HashMap<String, String> in Java, also eine String zu String-Map. Am einfachsten wäre es gewesen, wenn ich meine bereits vorhandene HashMap<String, Pointer>-Klasse nehmen würde, und einfach einen Pointer auf den String legen würde. Ich probiers mal aus.
|
Re: Speicherbereinigung von Strings
Ein String wird dann freigegeben, wenn keine Referenz mehr auf ihn existiert. Damit hat alzaimar für die Mehrzahl der Fälle (globale Variablen, Felder und lokale Variablen, die an höhere Gültigkeitsbereiche durchgereicht werden) recht. Den String musst du nicht unbedingt in eine Klasse packen, ein Record tut es genauso - allerdings ist der String selbst intern auch eine Art Klasse, also kannst du auch einfach nach Pointer und zurück casten ;)
|
Re: Speicherbereinigung von Strings
Ja, kann ich - aber der Speichermanager macht Hackfleisch daraus, hab es grad getestet. Mit nem record hab ichs jetzt nicht probiert, aber der String wurde offenbar freigegeben, das letzte Zeichen war unbrauchbar, nachdem ich den Pointer dereferenziert habe. Jetzt habe ich ihn in eine Klasse gewrappt und das ganze funktioniert. Danke trotzdem.
|
Re: Speicherbereinigung von Strings
Hallo,
ein einfacher TypeCast auf Pointer dürfte nicht ausreichen, damit unterläuft man die Referenzzählung. Zum Speichern und späteren Auslesen der Strings über Pointer kann man wie folgt vorgehen:
Delphi-Quellcode:
Das TList-Objekt ist natürlich nur ein Platzhalter für die tatsächliche Datenstruktur.
var
List : TList; i : Integer; ps : PString; begin List := TList.Create; for i := 0 to 9 do begin New (ps); ps^ := IntToStr(i); List.Add(ps); end; {...} for i := 0 to 9 do begin ps := PString(List[i]); ShowMessage (ps^); end; for i := 0 to 9 do Dispose (PString(List[i])); List.Free; end; Gruß Hawkeye |
Re: Speicherbereinigung von Strings
Das wollte ich so ungefähr wissen. Ich finde aber fast, dass eine Wrapper-Klasse eleganter ist.
|
Re: Speicherbereinigung von Strings
Oder du zählst einfach den Referenzzähler eins hoch. Der liegt 8 Byte vor der Stringaddresse. (und hinterher natürlich wieder eins runter :mrgreen:
|
Re: Speicherbereinigung von Strings
Geht das nur mit:
Delphi-Quellcode:
oder gibt es da eine elegantere Methode, wie z.B. eine Art _AddRef?
InterlockedIncrement(PInteger (Integer(MyString)-8)^);
[edit] Adresse des Strings berichtigt. @MyString ist die Adresse des Pointers, nicht der Speicherbereich des Strings![/edit] |
Re: Speicherbereinigung von Strings
An sowas dachte ich. Habe ich bisher auch nicht anders gemacht. Aber warum Lock Inc?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:35 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-2025 by Thomas Breitkreuz