Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Zugriff auf String^ (String pointer) (https://www.delphipraxis.net/191756-zugriff-auf-string%5E-string-pointer.html)

Pixel 16. Feb 2017 13:01

AW: Zugriff auf String^ (String pointer)
 
Ja ich denke ich hab es jetzt verstanden.

Delphi-Quellcode:
@String = Adresse die Auf String zeigt
String[0] = Länge
String[1] = Erster Char
@String[1] = Adresse von erstem Char

=>

Entweder PChar(@NormalerString[1] + 4); (gefährlich)

oder (einfacher, besser)

@NormalerString[5];

Neutral General 16. Feb 2017 13:20

AW: Zugriff auf String^ (String pointer)
 
Zitat:

@String = Adresse die Auf String zeigt
Ja, wenn dus richtig meinst :mrgreen:

String (ohne @) ist schon die Adresse auf den Zeichenkette des Strings.
@String ist die Adresse auf die Adresse auf die Zeichenkette des Strings

Oder anders gesagt: @String (ohne Index auf ein bestimmtes Zeichen) ist zu 99% falsch oder unnötig.
Delphi-Quellcode:
var str: String;
    pstr: PChar;
begin
  // Beides das gleiche
  // Die erste Zeile zeigt aber was intern bei @str[5] quasi passiert.
  // ==> str[5] = PChar(Integer(str) + 4)^ intern
  // ==> str ist schon ein Pointer
  pstr := @(PChar(Integer(str) + 4)^);
  pstr := @str[5];

himitsu 16. Feb 2017 18:08

AW: Zugriff auf String^ (String pointer)
 
Ein String ist mehr als nur Text, gefolgt von einer #0.
Wobei Delphi-Strings die #0 eigentlich nicht brauchen, denn "vor" dem Text (also vor der Stelle des ersten Zeichens, auf die der interne String-Pointer zeigt) liegt noch eine Längenangabe, der Referenzzähler und die CodePage-Informationen.
Und hinter dem letzten Zeichen liegen noch zwei #0-en, als Kompatibilität und um "schnell" in einen PChar casten zu können.

Fazit: Als "String" kann man den Zeiger nicht einfach so verschieben.
Ein Cast von String zu PChar geht immer,
aber andersrum geht's nimmer (hier muß man eine neue String-Variable erzeugen und da rein den PChar-Inhalt kopieren).

Mit einem PChar kann man das problemlos machen (also von einem PChar aus oder Anfangs auch von einem String/AnsiString/UnicodeString oder WideString),
denn dort zeigt der Zeiger wirklich "nur" auf ein Zeichen und dann so lange, bis eine #0 gefunden wird.

p80286 16. Feb 2017 21:51

AW: Zugriff auf String^ (String pointer)
 
Delphi-Quellcode:
mystring[0]
ist nur bei Shortstrings die Länge des Strings. Benutze bitte immer
Delphi-Quellcode:
length(mystring)
falls Du die Länge benötigst.

Gruß
K-H

Neutral General 17. Feb 2017 08:20

AW: Zugriff auf String^ (String pointer)
 
Zitat:

Zitat von p80286 (Beitrag 1361891)
Delphi-Quellcode:
mystring[0]
ist nur bei Shortstrings die Länge des Strings. Benutze bitte immer
Delphi-Quellcode:
length(mystring)
falls Du die Länge benötigst.

Stimmt nicht:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var str: String;
begin
  str := 'Hallo Welt!';
  Caption := IntToStr(PInteger(Integer(@str[1])-SizeOf(Integer))^);
end;
Length(mystring) ist natürlich trotzdem zu bevorzugen.

Sherlock 17. Feb 2017 08:28

AW: Zugriff auf String^ (String pointer)
 
Ohne konkreten Anwendungsfall und Not, würde ich mir heutzutage keine Gedanken mehr um Zeiger machen...speziell bei Strings. Moderne Strings sind mehr als nur simple Bytefolgen, da steckt zu viel dahinter, um es von Hand durchzuhecheln.

O'Neill

p80286 17. Feb 2017 10:50

AW: Zugriff auf String^ (String pointer)
 
Zitat:

Zitat von Neutral General (Beitrag 1361909)
Zitat:

Zitat von p80286 (Beitrag 1361891)
Delphi-Quellcode:
mystring[0]
ist nur bei Shortstrings die Länge des Strings. Benutze bitte immer
Delphi-Quellcode:
length(mystring)
falls Du die Länge benötigst.

Stimmt nicht:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var str: String;
begin
  str := 'Hallo Welt!';
  Caption := IntToStr(PInteger(Integer(@str[1])-SizeOf(Integer))^);
end;
Length(mystring) ist natürlich trotzdem zu bevorzugen.

Delphi-Quellcode:
const
  bstb='aaaaaaaaaa';
var
  i: integer;
  mystring: ansistring;

begin
  mystring:='';
  for i:=1 to 30 do
    mystring:=mystring+bstb;
  self.Button1.Caption:=format('%d -- %d',[length(mystring),mystring[0]]);
end;
ergibt:

[Fehler] Unit1.pas(38): Auf Element 0 kann nicht zugegriffen werden - 'Length' oder 'SetLength' verwenden
es ging ja explizit um MyString[0] mit irgendwelcher Pointerartistik kann man ja beinahe alles erreichen:)

Gruß
K-H

himitsu 17. Feb 2017 15:18

AW: Zugriff auf String^ (String pointer)
 
Zitat:

Zitat von Sherlock (Beitrag 1361910)
Ohne konkreten Anwendungsfall und Not, würde ich mir heutzutage keine Gedanken mehr um Zeiger machen...speziell bei Strings. Moderne Strings sind mehr als nur simple Bytefolgen, da steckt zu viel dahinter, um es von Hand durchzuhecheln.

Die interne Definition versteckt sich als Record in der System.pas.
Im Grunde genommen ist String recht einfach, wenn man sich einen Hauch auskennt.
* der Zeiger bei Strings zeigt auf das erste Zeichen und und nicht auf den Recordanfang.
* leere Strings sind NIL (theoretisch könnte man auch den Record mit der Daten-Länge 0 verwenden, aber eigentlich kommt das nie vor)
** drum kann man Strings/dynamische Arrays auch oft "schnell" mit Assigned oder =nil bzw. ='' prüfen, anstatt ein Length(x)=0 nehmen zu müssen
* Die beiden #0#0 am Ende werden da nicht erwähnt, aber sind immer da (wenn niemand einen Buffer-Overflow verbrockt hat)
** #0 für PChar-Ende und #0#0 für C-StringListen (#0 für WertEnde und #0#0 für ListenEnde, also ein '' als letzter Wert)
* Die Referenzzählung hat einen Wert für String-Konstanten (-1), welcher bei Speicheroperationen beachtet werden sollte.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:02 Uhr.
Seite 2 von 2     12   

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