本文整理自网络,侵删。
var s: AnsiString;begin s := '1234567890'; showmessage(s);end;
变量s的内存结构为A8 03 01 00 FF FF FF FF 0A 00 00 00 31 32 33 34 35 36 37 38 39 30 00
01~02 字节是代码页,如上面的0x03A8为十进制的936,表示简体中文GBK03~04 字节表示每个字符所占的字节数(ANSI为1,Unicode为2)05~08 字节是该字符串的引用计数09~12 字节是该字符串的字符个数13~?? 字节就是字符串实际的内容了?? 最后一个字节是00,字符串的结束符
对于string变量类型s,它实际上是一个指针,指向字符串首个字符的地址,也就是第13个字节
这里需要注意的是,在Delphi 2009以前的版本中是没有描述代码页的4字节的,而是直接从第05字节开始。
上面的字符串引用计数为什么会是0xFFFFFFFF呢?因为该字符串是常量,对于常量字符串,引用计数总是-1若有N处相同的字符串常量时,就有N份的拷贝,这样就造成了空间上的浪费,Delphi并未作出优化下面的代码就可以说明问题,两次显示的字符串内存地址不同。
procedure Foo();var s: AnsiString;begin s := '1234567890'; ShowMessage(IntToHex(Integer(@s[1]), 8));end; procedure TForm1.Button1Click(Sender: TObject);var s: AnsiString;begin s := '1234567890'; ShowMessage(IntToHex(Integer(@s[1]), 8)); Foo;end;接着看看下面的代码
var s: AnsiString;begin s := Caption; ShowMessage(IntToHex(Integer(@s[1]), 8));end;由于没有使用常量字符串,所以引用计数不再是-1A8 03 01 00 01 00 00 00 05 00 00 00 46 6F 72 6D 31 00
在知道了string的内存结构后,我们就可以通过代码来观测引用计数的值了
var s, s2: AnsiString; p: ^Integer;begin s := Caption; p := Pointer(@s[1]); Dec(p, 2); ShowMessage(IntToStr(p^)); // 1 s2 := s; // 引用计数+1了 ShowMessage(IntToStr(p^)); // 2end;
――――――――――――――――
原文链接:https://blog.csdn.net/aqtata/article/details/38905387
相关阅读 >>
Delphi win7,win2008,win2003,winxp 屏蔽ctrl+alt+del
Delphi combobox 只读 text属性可用的方法
用Delphi通过setupapi.dll列举和停用硬件设备
更多相关阅读请进入《Delphi》频道 >>