32位的Delphi中三种字符串:
1、ShortString——传统Pascal字符串类型,序列头部一个字节长度指示字符串长度,所以字符串最多只能有255个字符,字符类型ANSIChar。
2、AnsiString——可变长字符串类型,内存动态分配,引用计数,使用了更新前拷贝(copy-on-write)技术,理论上长度没有限制。字符类型ANSIChar。
3、WideString——与AnsiString相似,只是字符类型是WideChar(双字节Unicode字符)。
下面我们用一个类子来主要研究一下AnsiString在内存中的数据
1function StringStatus(const S: string) : string;
2begin
3 Result := Format('Address: $%x ' + sLineBreak
4 + 'Length: %d ' + sLineBreak
5 + 'References: %d ' + sLineBreak
6 + 'Value: %s'
7 , [Integer(S)
8 , {Length(S)}{运用Length函数会增加引用计数}
9 PInteger(Integer(S) - 4)^, PInteger(Integer(S) - 8)^, S]);
10end;
procedure TForm1.btn2Click(Sender: TObject);
begin
Str1 := 'Hello';
//Str2 := Str1;
mmo1.Clear;
mmo1.Lines.Add(StringStatus(Str1));
mmo1.Lines.Add(EmptyStr);
Str1 := 'World'; //copy-on-write技术,更新前拷贝
mmo1.Lines.Add(StringStatus(Str1));
end;
结果如下:
Address: $AA9D5C
Length: 5
References: 1
Value: Hello
Address: $AA9D7C
Length: 5
References: 1
Value: World
说明:
1、StringStatus函数用const传递参数至关重要
2、字符串长度和引用计数信息实际上保存在字符串中, 位于实际内容和字符串变量所指的内存位置之前,其负偏移量对字符串长度来说是-4(用Length 函数很容易得到这个值),对引用记数来说是-8,不过必须记住,以上关于偏移量的内部信息在未来的Delphi版本中可能会变,没有写入正式Delphi文档的特性很难保证将来不变