Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi String Gültigkeit + PChar Verwendung (https://www.delphipraxis.net/109112-string-gueltigkeit-pchar-verwendung.html)

stoxx 24. Feb 2008 18:23


String Gültigkeit + PChar Verwendung
 
Hallo ...


kann man sicher sein, dass ein String immer bis zum Ende einer funktion oder procedure gültig ist, oder wird der Referenzzähler schon nach der letzten Verwendung zurück gesetzt.

wenn man eine FunktionA hat, in dieser ist eine String Variable deklariert, man übergibt den String einem Object, und und dieses Object hält ein PChar auf diesen String.
Kann man sicher sein, dass der PChar bis zum Ende der FunktionA seine gültigkeit hat, oder kann es vorkommen, dass er dann falsch zeigt?

mkinzler 24. Feb 2008 18:25

Re: String Gültigkeit + PChar Verwendung
 
Zeig mal ein Beispiel für was du meinst

stoxx 24. Feb 2008 18:33

Re: String Gültigkeit + PChar Verwendung
 
Delphi-Quellcode:
procedure TForm1.test;
var s : String;
    obj : TMyClass;
    P : PChar;
begin


  obj := TMyClass.create;
 
  s := '32434';
  obj.machewas(s);
 
  // <-  ist hier der String noch ganz sicher verfügbar für das Object? 
  // wenn das Object keine eigene FMyStringKopie : String Variable hält,
  // sondern nur ein PChar
 
  // ist der String also noch da, zufällig da (weil vom speichermanager noch nicht überschrieben)
  // oder ist er ganz sicher noch da?
 
 
  P := obj.möchtePchar;
 
 
 
  obj.free;

 
  //  <- oder ist der String bis zum Ende der Funktion gültig?

end;

Larsi 24. Feb 2008 18:33

Re: String Gültigkeit + PChar Verwendung
 
Warum soll Delphi dich belügen???
Weißt net ob du das so meinst aber du könntest den string ja auch global erwähnen!

stoxx 24. Feb 2008 18:35

Re: String Gültigkeit + PChar Verwendung
 
nein, kein globaler String, sonst hätte ich das ja gemacht.

Larsi 24. Feb 2008 18:42

Re: String Gültigkeit + PChar Verwendung
 
Kannstes nicht ausprobieren? Label1.caption := deinpcharstring

stoxx 24. Feb 2008 18:45

Re: String Gültigkeit + PChar Verwendung
 
Zitat:

Zitat von Larsi
Kannstes nicht ausprobieren? Label1.caption := deinpcharstring

ja, er ist noch da, die Frage ist aber, ob er noch zufällig da ist, weil der Speicher noch nicht neu genutzt wurde, aber irgendjemand anderes ihn benutzen könnte. (anderer Thread);

omata 24. Feb 2008 19:02

Re: String Gültigkeit + PChar Verwendung
 
Der String ist ganz sicher bis zum Ende der Prozedur vorhanden. Er gehört ja auch der Prozedur und solche lokalen Variablen werden auf dem Stack abgelegt bzw. bei einem String wird auch nur die Adresse abgelegt. Dieser Stackinhalt muss erhalten bleiben, solange die Prozedur abläuft.

Anderer Thread? wie soll das gehen, das ist eine lokale Variable!

Gruss
Thorsten

stoxx 24. Feb 2008 19:40

Re: String Gültigkeit + PChar Verwendung
 
Zitat:

Zitat von omata
Der String ist ganz sicher bis zum Ende der Prozedur vorhanden. Er gehört ja auch der Prozedur und solche lokalen Variablen werden auf dem Stack abgelegt bzw. bei einem String wird auch nur die Adresse abgelegt. Dieser Stackinhalt muss erhalten bleiben, solange die Prozedur abläuft.

Anderer Thread? wie soll das gehen, das ist eine lokale Variable!

Gruss
Thorsten

hmm ... vielen Dank ... okay .. ich dachte, weil der Debugger ja manchmal anzeigt "Variable kann wegen Optimierung nicht angezeigt werden"
Wo ist die Variable dann hin, und warum kann der Debugger das manchmal nicht anzeigen da?

lg

Muetze1 24. Feb 2008 20:47

Re: String Gültigkeit + PChar Verwendung
 
Zitat:

Zitat von stoxx
Wo ist die Variable dann hin, und warum kann der Debugger das manchmal nicht anzeigen da?

Der Compiler optimiert deinen Code. Deine lokalen Variablen legt er im Normalfall auf dem Stack an. Diesen Speicherbereich kann der Debugger berechnen und somit drauf zugreifen. Wenn der Compiler aber nun optimiert und feststellt, dass du für den PChar die 4 Bytes für dessen Adresse bei dem einen Aufruf holst und dann ein paar Opcodes schon das letzte mal verwendest, dann optimiert er es so um, dass er erst gar kein Speicherplatz auf dem Stack dafür anlegt (Speicherzugriff muss adressiert werden und macht ein wenig Aufwand) sondern einfach den PChar in einem freien Register behält. Damit ist der Code schneller (optimiert), dafür weiss der Debugger aber nicht, wo (bzw. in welchen Register, etc) sich diese Variable gerade befindet.

stoxx 25. Feb 2008 18:43

Re: String Gültigkeit + PChar Verwendung
 
ok, vielen Dank :-)

sirius 26. Feb 2008 07:58

Re: String Gültigkeit + PChar Verwendung
 
Ein String muss auch die ganze Prozedur über auf dem Stack liegen, damit diese dynamische Variable (die ja vom Compiler verwaltet wird) auch immer zuverlässig freigegeben wird.
Dazu legt Delphi um die gesamte Prozedur automatisch ein try..finally, damit asuch im Fehlerfall der String freigegeben werden kann. dazu muss er allerdings immer auf dem Stack liegen (jeder Thread hat übrigens seinen eigenen Stack). Ich wüsste nicht, dass die Code-Optimierung einen String in die Register schiebt.

stoxx 26. Feb 2008 15:53

Re: String Gültigkeit + PChar Verwendung
 
Zitat:

Zitat von sirius
Ein String muss auch die ganze Prozedur über auf dem Stack liegen, damit diese dynamische Variable (die ja vom Compiler verwaltet wird) auch immer zuverlässig freigegeben wird.
Dazu legt Delphi um die gesamte Prozedur automatisch ein try..finally, damit asuch im Fehlerfall der String freigegeben werden kann. dazu muss er allerdings immer auf dem Stack liegen (jeder Thread hat übrigens seinen eigenen Stack). Ich wüsste nicht, dass die Code-Optimierung einen String in die Register schiebt.

ok .... wenn ich mir den RefCount vom String selber um eins erhöhen würde, damit Delphi am Ende der Procedure den String nicht freigibt.
(dann entsteht auch ein Speicherleck, wenn man es mal in einer Schleife testet)
Wie müsste ich den String dann sauber selber freigeben?
Und Manchmal steht der RefCount vom String in normalen Proceduren manchmal auf -1?

himitsu 26. Feb 2008 16:04

Re: String Gültigkeit + PChar Verwendung
 
auf -1 steht der, wenn er nicht im Speicher liegt.
z.B. wenn er von einer Konstante "geladen" wurde.

shmia 26. Feb 2008 16:09

Re: String Gültigkeit + PChar Verwendung
 
Zitat:

Zitat von stoxx
Und Manchmal steht der RefCount vom String in normalen Proceduren manchmal auf -1?

Das ist dann ein Stringliteral oder Resourcestring. Durch RefCount=-1 "weiss" Delphi, dass dieser String nicht freigegeben werden darf.

himitsu 26. Feb 2008 16:23

Re: String Gültigkeit + PChar Verwendung
 
an RefCount direkt würde ich nicht rumspielen.

ich behandle zwar Stringvaiablen wie Pointer (was sie ja im Grunde auch sind) und so kann man nette Dinge mit machen, aber ein "schöner" Weg ist das nicht gerade (wenn er auch einfach ist), aber wie du schon bemerkt hast, kann man sich so (falls man nicht aufpasst) ein Speicherleck einfangen.


was hindert dich eigentlich daran selber Speicher zu resservieren und freizugeben?
Delphi-Quellcode:
Var P: PChar;

P := GetMemory(Length(S) + 1);
MoveMemory(P, PChar(S), Length(S) + 1);
jetzt kannst du mit P alles machen, was du willst

und wenn der String nicht mehr benötigt wird, dann den Speicher per FreeMemory(P) wieder freigen.

stoxx 26. Feb 2008 16:58

Re: String Gültigkeit + PChar Verwendung
 
Zitat:

was hindert dich eigentlich daran selber Speicher zu resservieren und freizugeben?
Die Geschwindigkeit :-)


http://www.delphipraxis.net/internal...278&highlight=



ich will PChars auf den String halten, aber sicher sein, dass ich nicht ungültige PChars halte.
Falls doch mal jemand bei meinem StringExploder auf die Idee kommt, ihn länger zu haben, als die Procedure dauert :-)
Und ich jedes Kopieren oder Anlegen von Speicher vermeiden will :)
In dieser Lösung ...

himitsu 26. Feb 2008 21:21

Re: String Gültigkeit + PChar Verwendung
 
dann hat sich derjenige selbst drum zu kümmern, daß sein String lang genug am Leben bleibt.

schließlich hättest du dann noch das Problem mit dem Speicherleck.
oder wie meinst du soll dann bestimmt werden, wann der String freigegeben werden darf,
bzw. wo willst du dann das Freigeben des String veranlassen (wenn deine Prozedure schon lange beendet ist)?


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:43 Uhr.

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