代码说明
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异常。”
它总是重新分配字符串,这就是地址更改的原因。这也是一种获取没有被其他任何东西使用的字符串的方法。
更新:要完全正确,最好重新表述“更安全的假设它总是重新分配字符串”的说法。请参阅下面的注释以获取解释。