Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Stringverwaltung / Ansistring (https://www.delphipraxis.net/196584-stringverwaltung-ansistring.html)

AJ_Oldendorf 1. Jun 2018 10:16

Stringverwaltung / Ansistring
 
Hallo,
ich habe eine Frage zum AnsiString und dessen Verwaltung im Speicher.

Folgendes Konstrukt (ich möchte keine Diskussion über Nutzen/Zweck/Sinnhaftigkeit etc. des QT erzeugen):

Delphi-Quellcode:
//Global
var
  MyAnsi: AnsiString;

procedure TForm1.MakeStr(aStr: PAnsiString; Laenge: Integer);
var
  TmpStr : String[4];
begin
  SetLength(aStr^, 0);
  SetLength(aStr^, Laenge);

  TmpStr := 'HA';
  Move(TmpStr[1], aStr^[1], 2);
end;

procedure TForm1.MakeStr2(aStr: PAnsiString);
var
  NewMsgString : AnsiString;
begin
  NewMsgString := Copy(aStr^, 1, 2) + 'HALLO WELT';

  aStr^ := NewMsgString;
end;

procedure TForm1.MakeStr3(aStr: PAnsiString);
var
  NewMsgString : AnsiString;
begin
  NewMsgString := Copy(aStr^, 1, 2) + 'KURZ';

  aStr^ := NewMsgString;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MakeStr(@MyAnsi, SizeOf(Word));
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  MakeStr2(@MyAnsi);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  MakeStr3(@MyAnsi);
end;
Beim Aufruf von MakeStr, wird die Länge des Strings gesetzt auf die Länge, welche im Parameter übergeben wurde.
Anschließend wird etwas in den String geschrieben.

Im Aufruf von MakeStr2 wird das SetLength nicht aufgerufen aber die Länge des Ursprungsstrings vergrößert, da ich noch was hinten dran hänge.

Im Aufruf von MakeStr3 wird das SetLength nicht aufgerufen aber die Länge des Ursprungsstrings verkürzt, da ich am Ende was "abschneide".

Meine Frage ist nun, muss ich das SetLength eigentlich machen bzw. kann mir beim Aufruf von MakeStr2/MakeStr3 etwas im Speicher hängen bleiben?

Ich hoffe ich versteht meine Frage und könnt mir weiterhelfen.

himitsu 1. Jun 2018 10:46

AW: Stringverwaltung / Ansistring
 
AnsiString und UnicodeString und Ableitungen von AnsiString ala RawByteString und UTF8String sind LongStrings (die Technik)
WideString ist ein OLEString.
Der Typ String[x] und ShortString sind ShortStrings.

ShortString = Record (LängenByte in [0] und dahinter die Chars)
LongString = dynamisches Array mit ein paar Addons, wie implizit zwei Char #0 inher dem String und die Codepage wird auch gespeichert (Pointer auf die String-Verwaltungsstruktur)
OLEString = siehe BSTR und MSDN-Library durchsuchenSysAllocStringLen


PS: Die genauen Definitionen kann man sich in der System.pas ansehen und inzwischen wird das sogar in der OH gut beschrieben.

MakeStr ist ein Graus.
Bei weniger als 2 (genauer bei Len=1) knallt es nur zufäälig nicht, wegen der zusätzlichen zwei #0 im String, aber du zerstörtst/überschreibst damit diese Verwaltungsdaten, welche für Casts nach PChar existieren.
Und bei Len=0 knallt der Aufruf definitiv, da ein Leerstring NIL ist und keine Verwaltungsdaten besitzt, in die du reinschreiben könntest.



Zitat:

ich möchte keine Diskussion über Nutzen/Zweck/Sinnhaftigkeit etc. des QT erzeugen
Warum nicht?

AJ_Oldendorf 1. Jun 2018 10:49

AW: Stringverwaltung / Ansistring
 
Also verstehe ich dich richtig, dass SetLength bei einem AnsiString macht keinen Sinn bzw. ist nicht notwendig?
Also passiert mit meinen MakeStr2 und MakeStr3 nichts, dass irgendwo etwas hängen bleibt oder verloren geht?

MakeStr war nur ein Beispiel. Ist mir klar was passiert wenn da Laenge <2 übergeben wird. Aber danke

himitsu 1. Jun 2018 10:55

AW: Stringverwaltung / Ansistring
 
Zitat:

Zitat von AJ_Oldendorf (Beitrag 1403609)
Also verstehe ich dich richtig, dass SetLength bei einem AnsiString macht keinen Sinn bzw. ist nicht notwendig?

Es kommt drauf an.

Delphi-Referenz durchsuchenUniqueString
Wenn man sichergehn will, dass der Speicher nur dir gehört, denn LongString sind referenzgezählt.
Zwei Variablen auf den "selben" Stringinhalt zeigen auf die selbe Adresse.

mkinzler 1. Jun 2018 10:55

AW: Stringverwaltung / Ansistring
 
Setlength bringt schon etwas, aber man muss eine Referenz nicht dereferenzieren (wie einen Zeiger)
Delphi-Quellcode:
 SetLength(aStr, Laenge);
Setzen auf 0 ist überflüssig.

AJ_Oldendorf 1. Jun 2018 11:07

AW: Stringverwaltung / Ansistring
 
Ok, also wenn meine Task der einzige Eingentümer des AnsiStrings ist und ich den mal vergrößere oder verkürze (wie MakeStr2/MakeStr3), dann ist das kein Problem. Richtig?

bernau 1. Jun 2018 14:11

AW: Stringverwaltung / Ansistring
 
Zitat:

Zitat von AJ_Oldendorf (Beitrag 1403606)
Folgendes Konstrukt (ich möchte keine Diskussion über Nutzen/Zweck/Sinnhaftigkeit etc. des QT erzeugen):


Mich würde trotzdem interessieren, weswegen du so ein Konstrukt benötigst. Geschwindigkeit?

Ich habe mir abgewöhnt mit Pointern bei Strings zu arbeiten.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:47 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