代码说明

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's now different, e.g. 11423804
end;





为什么System.SetLength(Str, Len)导致Str的地址发生变化?
有没有办法消除SetLength的这种副作用,这样我就不必将Str的新地址重新分配给PStr了?

最佳答案

正如help on System.SetLength所说:“在调用SetLength之后,保证S引用了唯一的字符串或数组,即引用计数为1的字符串或数组。如果没有足够的内存来重新分配变量, SetLength引发EOutOfMemory异常。”

它总是重新分配字符串,这就是地址更改的原因。这也是一种获取没有被其他任何东西使用的字符串的方法。

更新:要完全正确,最好重新表述“更安全的假设它总是重新分配字符串”的说法。请参阅下面的注释以获取解释。

07-28 06:41