Autor |
Beitrag |
F34r0fTh3D4rk
      
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Mo 21.03.05 16:05
ja, wird dieser denn aber nicht trotzdem freigegeben ?
|
|
SchelmVomElm
      
Beiträge: 154
W2K Pro
D5 Pro
|
Verfasst: Mo 21.03.05 16:07
Wenn ich einen hätte würd ich ihn auch posten. Und wenn man es schon nicht besser weiss, würde ich erst recht davon ausgehen dass ein Speicherleck gibt und mich drum kümmern. Gehört sich einfach so.
_________________ for(;P("\n"),R--;P("|"))for(e=C;e--;P("_"+(*u++/  %2))P("|"+(*u/4)%2);
|
|
opfer.der.genauigkeit
      
Beiträge: 754
Erhaltene Danke: 1
|
Verfasst: Mo 21.03.05 16:07
Aber mit @ holst du dir den Offset der variable.
Klar, daß @p dann nicht gleich @s, das sind zwei völlig verschiedene Variablen.
Um so mehr, wird Delphi sich selbstständig um p kümmern und dabei spielt es keine Rolle wohin der Zeiger zeigt.
Achja, ganz nebenbei hier mal n Auszug aus der Hilfe:
Zitat: |
Ein PChar ist ein Zeiger auf einen nullterminierten String mit Zeichen des Typs Char. Jeder der drei Zeichentypen besitzt einen integrierten Zeigertyp:
PChar ist ein Zeiger auf einen nullterminierten String mit 8-Bit-Zeichen.
PAnsiChar ist ein Zeiger auf einen nullterminierten String mit 8-Bit-Zeichen.
PWideChar ist ein Zeiger auf einen nullterminierten String mit 16-Bit-Zeichen.
PChars bilden mit kurzen Strings den ursprünglichen String-Typ von Object Pascal. Sie wurden als Kompatibilitätstyp zur Sprache C und zur Windows-API eingeführt.
|
//Edit:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| var s: string; p: pchar; begin s := 'test'; p := pchar(s);
if pointer(p) = pointer(s) then showmessage('gleich'); end; |
Ich verpeil eh grad alles.. *ne kippe rauchen geht*
_________________ Stellen Sie sich bitte Zirkusmusik vor.
|
|
SchelmVomElm
      
Beiträge: 154
W2K Pro
D5 Pro
|
Verfasst: Mo 21.03.05 16:13
_________________ for(;P("\n"),R--;P("|"))for(e=C;e--;P("_"+(*u++/  %2))P("|"+(*u/4)%2);
|
|
opfer.der.genauigkeit
      
Beiträge: 754
Erhaltene Danke: 1
|
Verfasst: Mo 21.03.05 16:30
Eigentlich bezieht sich das auf die letzte Aussage von retnyg
und soll ausdrücken, daß p hier nicht freigegeben werden muß.
_________________ Stellen Sie sich bitte Zirkusmusik vor.
|
|
retnyg
      
Beiträge: 2754
SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
|
Verfasst: Mo 21.03.05 16:35
variablen werden vom delphi-compiler von haus aus selber freigegeben, mit Dispose gibt man Objekte frei.
aber woher soll der compiler wissen, wo der freizugebende pchar im speicher ist, wenn der zeiger drauf verändert wird ? ich glaub nicht dass für jede variable zwei pointer gespeichert werden.
_________________ es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Mo 21.03.05 17:11
Es kommt drauf an, wie der String gespeichert ist. Bei "hardcoded" Strings ist es anders als bei Strings, die intern mit GetMem erzeugt wurden. Hier einige Beispiele, die das verdeutlichen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| Var S : String; P : PChar; begin S := 'abcdefg'; P := PChar(S); S[2] := 'B'; ShowMessage(P); S := 'abcd'; S := S + 'efg'; P := PChar(S); S[2] := 'B'; ShowMessage(P); end; | Siehe z.B. auch hier: Reverse (Hier wird ein PChar-Pointer ebenso verändert).
Ich wage mal zu behaupten, dass bei nicht hardgecodeten Strings gilt: p := PChar(S) ist äquivalent zu p := @S[1].
Könnte mich aber täuschen, das hier basiert lediglich auf Beobachtungen....
Übrigens hab ich oben (weiss nicht mehr wo) einen Denkfehler gesehn: p ist natürlich nie gleich @S!
Wenn p am gleichen Ort gespeichert ist wie S, dann gilt: p=@S[1].
|
|
opfer.der.genauigkeit
      
Beiträge: 754
Erhaltene Danke: 1
|
Verfasst: Mo 21.03.05 17:41
retnyg hat folgendes geschrieben: | variablen werden vom delphi-compiler von haus aus selber freigegeben. |
Jup, und was anderes als ne Variable ist es nicht.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:
| var p1, p2, p3, p4: pointer; pc: pchar; s : string; c1, c2: char; begin
s := 'TEST';
pc := pchar(s);
p1 := pointer(s); p2 := pointer(pc); p3 := @s; if p1 = pointer(p3^) then showmessage('gleich'); p4 := @pc; if p2 = pointer(p4^) then showmessage('gleich');
inc(pc); if @pc = p4 then showmessage('gleich');
end; |
Moderiert von Tino: Delphi-Tags hinzugefügt.
_________________ Stellen Sie sich bitte Zirkusmusik vor.
Zuletzt bearbeitet von opfer.der.genauigkeit am Mo 21.03.05 17:45, insgesamt 1-mal bearbeitet
|
|
SchelmVomElm
      
Beiträge: 154
W2K Pro
D5 Pro
|
Verfasst: Mo 21.03.05 17:42
Zitat: | p := PChar(S) ist äquivalent zu p := @S[1] |
Also wenn Du mit S einen Pascal string meinst kann das nicht sein, denn der muss keine Nullterminierung enthalten!
Delphi-Quelltext 1: 2:
| S := S + #0; p := @S[1]; |
_________________ for(;P("\n"),R--;P("|"))for(e=C;e--;P("_"+(*u++/  %2))P("|"+(*u/4)%2);
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Mo 21.03.05 17:49
Der normale String (= implizit AnsiString) ist nullterminiert, obwohl du das nicht zu spüren bekommst!
Der ist unter Umständen sogar doppelt nullterminiert (wegen den WideChars!).
Wenn du's nicht glaubst, siehe system.pas!
|
|
retnyg
      
Beiträge: 2754
SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
|
Verfasst: Mo 21.03.05 17:56
fazit: in diesem speziellen fall wird kein speicherleck erzeugt (ausser ein hartgecodeter string wird DIREKT hergenommen, also nicht über einen prozedureaufruf), es ist aber gefährlich, zeigertypen herumzubiegen wenn man nicht genau weiss was man tut (und ich bin mir sicher dass das bei f34ar0fth3d4rk der fall war  ), weswegen man es vermeiden sollte.
lieber manuell einen zeiger des typs pointer erstellen und dann mit diesem herumwerkeln...
_________________ es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
|
|
F34r0fTh3D4rk
      
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Mo 21.03.05 17:56
wenn man mehrere strings zusammenfügt, werden die nullen dann entfernt ?
kann ja sein, dass der string dadurch immer mehr bytes schluckt ?!
und der code war ja zuerst auch nur für das zeichen #0 gedacht, deswegen hats ja auch anfangs funktioniert, wenn man eigene trennzeichen nehmen will muss man das ende des strings extra abfragen, weil es nicht = trennzeichen ist
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Mo 21.03.05 17:58
Natürlich werden die Nullen zuerst entfernt. Wenn du wüsstest, was alles abgeht, wenn man zwei Strings addiert... Du würdest staunen! 
|
|
F34r0fTh3D4rk
      
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Mo 21.03.05 17:59
hatte bis jetzt noch nicht zeit und bock mir das anzuschauen, deshalb einige wissenslücken 
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Mo 21.03.05 18:05
Delphi-Quelltext 1: 2:
| S := 'Hallo '+A+' und '+B+' '+IntToStr(I); S := Format('Hallo %s und %s %d',[A,B,I]); |
Was denkst du, welche Variante ist effizienter? Du ahnst absolut richtig
Zugegeben, IntToStr ruft Format auf, aber auch ohne IntToStr ist die zweite Methode schneller....
|
|
hansa
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Mo 21.03.05 19:06
Daß mit festen Feldlängen sämtliche eventuell aufgetauchten Probleme gar nicht erst auftauchen würden, das merkt wohl keiner.  Das einzig brauchbare, was hier steht ist der Beitrag, von Delphifan, man könne bei Zahlen ruhig ein Trennzeichen verwenden.
Nur : wo liegt der Vorteil davon überhaupt ? Mir ist niemand bekannt, der sich heute noch auf CSV einläßt, nur weil in den 50er Jahren irgendjemand mal bei 8-Bit Zeichensätzen sich ein seltenes Zeichen dafür ausgedacht hat.
_________________ Gruß
Hansa
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Mo 21.03.05 19:12
Bei festen Feldlängen gibt's dafür andere Probleme: Sie sind weniger gut editierbar, und es kann vorkommen, dass man plötzlich zu wenig Pla
|
|
retnyg
      
Beiträge: 2754
SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
|
Verfasst: Mo 21.03.05 19:14
würde ich nicht sagen, csv ist immer noch die einfachste möglichkeit ne datenbank zu erstellen.
n paar werte mit 10 zeilen code in ne csv schreiben, die kann dann mit excel geöffnet werden und man hat alle werte in den richtigen spalten.
_________________ es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
|
|
hansa
      
Beiträge: 3079
Erhaltene Danke: 9
|
Verfasst: Mo 21.03.05 19:52
Ich gebe es bald auf. Angenommen 3 Integer stehen in einer Zeile. Jede hat 10 Stellen. Ein paar Werte auslesen aus einer Textdatei geht dann so :
nicht CSV :
Delphi-Quelltext 1: 2: 3:
| Zahl1 := StrToInt (copy (zeile,1,10)); Zahl2 := StrToInt (copy (zeile,11,10)); Zahl3 := StrToInt (copy (zeile,21,10)); |
mit CSV und keiner festen Feldlänge sähe es z.B. so aus :
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| SemikolonPos := pos (';',Zeile); HilfStr := copy (zeile,1,SemikolonPos-1); Zahl1 := StrToInt (copy (HilfStr,1,10)); delete (zeile,1,SemikolonPos); SemikolonPos := pos (';',Zeile); HilfStr := copy (zeile,1,SemikolonPos-1); Zahl2 := StrToInt (copy (HilfStr,1,10)); delete (zeile,1,SemikolonPos); SemikolonPos := pos (';',Zeile); HilfStr := copy (zeile,1,SemikolonPos-1); Zahl3 := StrToInt (copy (HilfStr,1,10)); delete (zeile,1,SemikolonPos); |
Handelt es sich nicht um Zahlen, dann hat man sowieso wohl verloren, denn man stelle sich mal vor, irgendjemand stellt aus Versehen die Tastatur auf englisch um. Er will eingeben : "östlich" und wegen geringer Schreibmaschinenkenntnisse achtet er mehr auf die Tastatur als auf das was tatsächlich da steht. Und das ist dann ";stlich".
Jetzt kommt alles mitsamt unbewußten Schreibfehlern in eine Datei und das Programm achtet nur auf ; Da ist aber jetzt einer zuviel drin und das Programm läuft nicht bis zum Ende durch. Die bewußte Eingabe des Trennzeichens ist dabei noch völlig außer acht gelassen.
Nimmt man ein anderes "Trennzeichen", so wird sich kaum was ändern. Es kracht irgendwann doch.
Das Argument mit Excel ist übrigens auch nur Theorie. Das kommt mit falschen Zeichen in einer "CSV" Datei genauso wenig zurecht, wie jedes andere Programm auch.
Der nächste Nachteil ist, daß man im Fehlerfall einen Editor getrost vergessen kann. In einer Textdatei ein ; zuviel zu entdecken ist fast unmöglich.
_________________ Gruß
Hansa
|
|
retnyg
      
Beiträge: 2754
SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
|
Verfasst: Mo 21.03.05 20:07
den zwoten codeteil kannst du dir sparen wenn du die explode funktion nimmst.
klar ist csv fehleranfällig wenn in texten semikolons vorkommen können.
wenn dies aber nie der fall sein wird, kann man das getrost verwenden.
bsp.: ich hatte mal ein ping-programm geschrieben das alle hosts eines subnetzes anpingt, und dann jeweils die hostnamen, ip-adresse und roundtrip time in ein csv schreibt.
die csv dann in excel geöffnet und schon hat man eine tabellierte übersicht aller rechner im netz.
_________________ es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
|
|
|