6 Stimmen

Delphi Zeichenketten und Referenzzählung

Delphi verwendet Referenzzählung mit Zeichenfolgen.

Bedeutet dies, dass es nur eine Speicherzuweisung für '1234567890' gibt und alle a, b, c, d, e und f darauf verweisen?

 type  
   TFoo = class
    s: string;
   end;

  const 
    a = '1234567890';
    b = a;
    c : string = a;

  var
    d: string;
    e: string;
    f: TFoo;

  function GetStr1(const s: string): string;
  begin
   Result := s;
  end;

  function GetStr2(s: string): string;
  begin
   Result := s;
  end;

  begin
   d := GetStr1(b);
   e := GetStr2(c);
   f := TFoo.Create;
   f.s := a;
  end;

10voto

Barry Kelly Punkte 40566

Ja, in Ihrem spezifischen Beispiel gibt es nur eine Zuweisung. Wenn Sie UniqueString verwendet hätten, wie mghie sagt, oder wenn Sie den String dynamisch aufgebaut hätten, würden Sie am Ende eine neue String-Zuweisung erhalten, auch wenn der Stringinhalt mit einem anderen String übereinstimmt.

Ein interessanter Fakt über Ihr spezifisches Beispiel: Tatsächlich wird überhaupt kein Speicher für den String '1234567890' allokiert. Die Daten für String-Konstanten werden im ausführbaren Bild auf der Festplatte gespeichert und vom Betriebssystem in den Speicher geladen, wenn der Code darauf zugreift. Es nimmt Speicheradresse ein, als Teil der gesamten in-Memory-Zuordnung des ausführbaren Moduls, aber da es vom ursprünglichen ausführbaren Bild auf der Festplatte unterstützt wird, bildet es keinen Teil des committeten Speichers des Prozesses und benötigt keine Unterstützung in der Auslagerungsdatei.

Zum Beispiel wird dieses Programm bei der Ausführung einen Zugriffsverletzungsfehler melden:

{$apptype console}
uses SysUtils;

const
  s = '1234567890';
procedure Change(const r: string);
var
  p: PChar;
begin
  p := PChar(r);
  p^ := 'x';
end;

begin
  try
    Change(s);
  except
    on e: Exception do
      Writeln(e.Message);
  end;
end.

6voto

mghie Punkte 31618

Kleiner Zusatz zur Antwort von jxac:

Eine Kopie wird auch erstellt, wenn UniqueString() im Code aufgerufen wird, wenn ein Zeichen im String über [] zugegriffen wird und wenn der String in PChar umgewandelt wird. Dies geschieht auch dann, wenn der PChar und das String-Element nur gelesen werden.

Es ist wichtig zu wissen, wie man einen eindeutigen String aus einem potenziell gemeinsam genutzten erzwingt, da es Windows-API-Funktionen gibt, die nicht mit einem schreibgeschützten Zeiger aufgerufen werden dürfen, wie es bei einem PChar zu einer String-Konstante der Fall ist. In diesem Fall muss die Konstante zuerst in eine Variable kopiert werden, damit durch das Umwandeln ein PChar zurückgegeben wird, der auf einen beschreibbaren Speicherplatz zeigt.

5voto

user262976 Punkte 1934

Ja, die Zeichenketten werden ref-counted, eine Kopie wird nur erstellt, wenn die Inhalte über eine Variable geändert werden (Kopieren beim Schreiben Semantik), mehr Informationen hier:

http://www.codexterity.com/delphistrings.htm

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X