Why does System.SetLength (Str, Len) cause the Str address to change?

Code illustration

procedure TForm1.FormCreate(Sender: TObject);
var
  Str: string;
  PStr: PChar;
begin
  Str := 'This a string.';
  PStr := Pointer(Str); // PStr holds the address of the first char of Str
  ShowMessage(IntToStr(Longint(PStr))); // It displays e.g. 4928304

  Setlength(Str, 20);

  // I don't know what actually happens in the call for SetLength() above,
  // because the address of Str changes now, so the PStr not valid anymore.

  // This is a proof of the fact
  PStr := Pointer(Str);
  ShowMessage(IntToStr(Longint(PStr))); // It now different, e.g. 11423804
end;

Question

  • Why System.SetLength(Str, Len)does it change the address of Str?
  • Is there a way to nullify this side effect SetLengthso that I don’t need to reassign the new Str address to PStr?
+5
source share
5 answers

As help on System.SetLength says: "After calling SetLength, S is guaranteed to refer to a unique string or array, i.e. a string or array with a reference number of one. If there is not enough memory to redistribute the variable, SetLength throws an EOutOfMemory exception."

, . , .

: , : " , ". . .

+10

Delphi, , , , (, ).

, , .

.

+8

, , , , - ( ), .

, :

var s1, s2: string;
begin
  s1 := 'test'+IntToStr(SomeNumber);
  s2 := s1;

Delphi , . s1 s2 , Delphi "", .

s1:

SetLength(s1, 4);

Delphi s2 s1 inplace, . s1 s2, , 1.

, , , , .

+4

Delphi String.

, PChar String.

+1

...

1. ldsandon, SetLength , . , 2 , , . , , StringOfChar('A',5), SetLength ( )

2. , . :

  procedure someproc
  var Obj1, obj2 : TObject;
  begin
  [...]
    obj2 := Obj1;
    Obj1 := nil;
    //I want Obj2 to be also nil here since obj1 is nil...
  end;

, PStr , , , .

-:

procedure TForm1.FormCreate(Sender: TObject);
var
  Str: string;
  PStr: PChar absolute Str;
begin

PStr, Str.

Secondly:

procedure TForm1.FormCreate(Sender: TObject);
var
  Str: string;
  function PStr: PChar
  begin
    Result := PChar(Str);
  end
begin

But it's always best to just use "PChar (Str)", where you need to access your string as Pchar.

Also, do not fake this if you are writing to a string through the PChar variable, you must make sure that the string has a reference count of 1 first (by calling UniqueString or SetLength).

+1
source

All Articles