Autor |
Beitrag |
SchelmVomElm
      
Beiträge: 154
W2K Pro
D5 Pro
|
Verfasst: Mo 21.03.05 13:07
Also wie das gehen soll ist mir auch nicht klar! Wenn WordPos in der Schleife nicht 0 erreicht hat die Funktion nicht mal einen definierten Rückgabewert! Also, was soll das?
_________________ for(;P("\n"),R--;P("|"))for(e=C;e--;P("_"+(*u++/  %2))P("|"+(*u/4)%2);
|
|
F34r0fTh3D4rk
      
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Mo 21.03.05 14:38
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| Function WortExtrahieren(Text: string; Wort: Word; Trennzeichen: Char): string; var p : PChar; begin p := PChar(Text); repeat Dec(Wort); while p^ <> Trennzeichen do begin if Wort = 0 then Result := Result + p^; Inc(p); end; if Wort = 0 then Exit; Inc(p); until p^ = Trennzeichen; end;
str:= 'Hallo;Du;Da'; str2:= WortExtrahieren(str, 1, ';'); |
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Mo 21.03.05 14:44
Mit dem Beispiel wird's schon viel klarer.
Scheint zu funktionieren, nur: Das letzte Wort lässt sich nicht korrekt extrahieren:
Delphi-Quelltext 1:
| WortExtrahieren('a;b;c',3,';'); |
Und: Wie weiss ich eigentlich, dass ich am Ende des Strings bin?
WortExtrahieren('a;b;c',4,';');gibt eine Endlosschleife. Ausserdem kann das String auch mal leer sein...
|
|
F34r0fTh3D4rk
      
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Mo 21.03.05 14:47
ich habe gerade einen fehler in delphi enddeckt, ich habe ein wort per random auswählen und als showmessage anzeigen lassen, wenn das letzte wort ausgewählt wurde kommt kein msg fenster sondern ein formular mit unendlicher breite und links oben ein label auf dem das wort steht, ok button fehlt und X lässt sich auch net erreichen, weils nach rechts hin unendlich lang ist. 
|
|
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 14:48
wenn ich das richtig sehe wird bei dunkelfürchters code einfach der pointer erhöht, was ein speicherleck erzeugt, der PChar kann nicht mehr freigegeben werden weil der pointer nicht mehr passt
_________________ 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 14:50
ich glaube der fehler, dass das letzte wort net ausgelesen wird lässt sich so beheben:
Delphi-Quelltext
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Mo 21.03.05 14:52
Wollt ich soeben auch schreiben. @F34r0fTh3D4rk: Das ist kein Delphi-Fehler, sondern ein Folgefehler wegen deiner Prozedur. Auch wenn der Pointer korrekt vernichtet würde spuckt deine Prozedur Unsinn beim letzten Wort aus: Du testest nirgends auf das Ende des Strings!!
//Edit: Hab deinen Post erst jetzt gelesen. Lässt sich so nur bedingt beheben... Das ist doch keine Lösung  Woher soll man überhaupt wissen, wieviele Einträge der String hat? Die Strings kommen aus einer Datei, da kann eine Zeile auch mal leer sein!!
Wie dem auch sei: Die ursprüngliche Frage ist schon längst beantwortet. Lassen wir's sein!
|
|
F34r0fTh3D4rk
      
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Mo 21.03.05 15:04
ich habs gerade so versucht, das ist aber schwachsinn, wie kann ich denn in meinem code das ende des strings abfragen ohne extra noch einen zähler einzubauen ?
Delphi-Quelltext 1:
| until (p^ = Trennzeichen) or (not (ord(p^) in [1..255])); |
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Mo 21.03.05 15:08
p ist nullterminiert. Da brauchst du keinen Zähler. Du solltest aber eine while-Schleife benützen, da das erste Zeichen schon eine #0 sein kann.
Übrigens @retnyg: Gibt's wirklich ein Speicherleck? PChar liefert hier doch nur nen Zeiger auf Text zurück und alloziert keinen neuen Speicher.
//Edits 1,2: Sorry, komische Satzkonstruktionen geflickt 
Zuletzt bearbeitet von delfiphan am Mo 21.03.05 15:13, insgesamt 2-mal bearbeitet
|
|
F34r0fTh3D4rk
      
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Mo 21.03.05 15:11
genau 
|
|
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 15:16
Zitat: | Delphi-Quelltext 1: 2: 3:
| p : PChar; begin p := PChar(Text); | |
hier wird doch ein neuer PCHar erstellt, und der wert von text reinkopiert. danach wird der pointer "verbogen", wie soll der kompiler wissen was er nun wieder freigeben kann ?
_________________ es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
|
|
opfer.der.genauigkeit
      
Beiträge: 754
Erhaltene Danke: 1
|
Verfasst: Mo 21.03.05 15:23
Wieso sollte das n Speicherleck erzeugen?
p ist der Zeiger auf den String.
Der String wird von Delphi eh seperat behandelt.
p = pchar(s) und d.h. p ist der zeiger von s .. wird also s, von Delphi, freigegeben ist der pointer eh müll..
Sinnvoll wäre da noch p = nil. Schöner wär's allerdings.
Versucht mal den pointer so freizugegeben Dispose(p) .. viel Spaß mit der Exception.
_________________ Stellen Sie sich bitte Zirkusmusik vor.
|
|
F34r0fTh3D4rk
      
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Mo 21.03.05 15:25
Zitat: |
Sinnvoll wäre da noch p = nil. Schöner wär's allerdings.
|
wo ?
|
|
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 15:26
_________________ 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 15:26
so funktionier das aber leider net
|
|
opfer.der.genauigkeit
      
Beiträge: 754
Erhaltene Danke: 1
|
Verfasst: Mo 21.03.05 15:45
Ok,
ich seh's ein.. blöd formuliert.
Du hast recht retnyg.. ist kein zeiger auf string.
*sfz*
Ok, besser ausgedrückt.
p := pchar(s);
Ein PChar ist ein Zeiger auf einen nullterminierten String mit Zeichen des Typs Char.
p muß und kann nicht freigegeben werden in diesem fall, da s von delphi eh freigegeben wird.
p zeigt aber weiterhin auf den Text, da Delphi den Speicher nicht mit Nullen vollschreibt, sondern nur die Referenz von s tötet.
Naja.. deshalb p := nil am Ende setzen, sofern man das möchte.
Würde man z.B. das hier machen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| .. private globalP: pchar; .. var s: string; p: pchar; begin s := 'test'; p := pchar(s); globalP := p; end;
procedure irgendwas; begin showmessage(globalp); end; |
Naja, ich hoffe meine Aussagen stimmen, sonst muß ich mich wohl heute einbuddeln und nochmal das Thema mit den Zeigern durchkämpfen. 
_________________ Stellen Sie sich bitte Zirkusmusik vor.
|
|
F34r0fTh3D4rk
      
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Mo 21.03.05 15:49
oha, bin ich dumm, so muss es lauten:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| Function WortExtrahieren(Text: string; Wort: Word; Trennzeichen: Char): string; var p : PChar; begin p:= PChar(Text); repeat Dec(Wort); while p^ <> Trennzeichen do begin if Wort = 0 then Result := Result + p^; if p^ = #0 then Exit; Inc(p); end; if Wort = 0 then Exit; Inc(p); until (p^ = Trennzeichen); P:= nil; end; |
|
|
SchelmVomElm
      
Beiträge: 154
W2K Pro
D5 Pro
|
Verfasst: Mo 21.03.05 15:53
p ist ein Zeiger auf das erste Zeichen des Strings.
Der Speicher für den gesammten nullterm. string ist reserviert.
Nach der Benutzung gibt Delphi den Speicher wieder frei.
Und zwar von p bis #0. p hat sich aber verändert und ob der Compiler das merkt und entsprechend handelt ist hier die Frage!
Durchaus diskussionswürdig wie ich finde - ich glaub das gibt 'nen Leck!
_________________ for(;P("\n"),R--;P("|"))for(e=C;e--;P("_"+(*u++/  %2))P("|"+(*u/4)%2);
|
|
F34r0fTh3D4rk
      
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Mo 21.03.05 15:55
hier gehn die meinungen auseinander, wo ist der beweis ?
|
|
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:03
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure TForm1.Button1Click(Sender: TObject); var s: string; p:pchar; pp, ps: pointer; begin s:='bla'; p:=pchar(s); ps:=@s; pp:=@p; if ps <> pp then showmessage('uneven'); end; |
hier dran sieht man, dass die funktion PChar(String) zuerst einen neuen, null-terminierten string erzeugt und anschliessend darauf zeigt, es wird also nicht einfach ein pointer auf den bereits existierenden string erstellt.
_________________ es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
|
|