• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Delphi的String内存结构(够清楚)good

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
 
 
  1. var  
  2.   s: AnsiString;  
  3. begin  
  4.   s := '1234567890';  
  5.   showmessage(s);  
  6. end;  


变量s的内存结构为(一共12个辅助字节,以前是8个字节)
(字符串编码)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,表示简体中文GBK
03~04 字节表示每个字符所占的字节数(ANSI为1,Unicode为2)
05~08 字节是该字符串的引用计数
09~12 字节是该字符串的字符个数
13~?? 字节就是字符串实际的内容了
??    最后一个字节是00,字符串的结束符

 

对于string变量类型s,它实际上是一个指针,指向字符串首个字符的地址,也就是第13个字节

这里需要注意的是,在Delphi 2009以前的版本中是没有描述代码页的4字节的(代码页+字符宽度),而是直接从第05字节开始(引用计数)。

 

上面的字符串引用计数为什么会是0xFFFFFFFF呢?因为该字符串是常量,对于常量字符串,引用计数总是-1
若有N处相同的字符串常量时,就有N份的拷贝,这样就造成了空间上的浪费,Delphi并未作出优化
下面的代码就可以说明问题,两次显示的字符串内存地址不同。

[delphi] view plain copy
 
 
  1. procedure Foo();  
  2. var  
  3.   s: AnsiString;  
  4. begin  
  5.   s := '1234567890';  
  6.   ShowMessage(IntToHex(Integer(@s[1]), 8));  
  7. end;  
  8.   
  9. procedure TForm1.Button1Click(Sender: TObject);  
  10. var  
  11.   s: AnsiString;  
  12. begin  
  13.   s := '1234567890';  
  14.   ShowMessage(IntToHex(Integer(@s[1]), 8));  
  15.   Foo;  
  16. end;  

接着看看下面的代码

[delphi] view plain copy
 
 
  1. var  
  2.   s: AnsiString;  
  3. begin  
  4.   s := Caption;  
  5.   ShowMessage(IntToHex(Integer(@s[1]), 8));  
  6. end;  

由于没有使用常量字符串,所以引用计数不再是-1
(代码页)A8 03 (字符宽度)01 00 (引用计数是1)01 00 00 00 (字符串长度)05 00 00 00 (字符内容)46 6F 72 6D 31 (结束符)00

在知道了string的内存结构后,我们就可以通过代码来观测引用计数的值了

[delphi] view plain copy
 
 
    1. var  
    2.   s, s2: AnsiString;  
    3.   p: ^Integer;  
    4. begin  
    5.   s := Caption;  
    6.   p := Pointer(@s[1]);  // 应该是得到s[1]的地址,即第一个字符的地址
    7.   Dec(p, 2);  // 前移2个单位(8个字节,因为每个^integer类型的数据长度是4)
    8.   ShowMessage(IntToStr(p^));  // 1,引用计数为1
    9.   
    10.   s2 := s;                    // 引用计数+1了  
    11.   ShowMessage(IntToStr(p^));  // 2,引用计数为2
    12. end;  

http://blog.csdn.net/aqtata/article/details/38905387


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
matlab图的坐标名称、字体、字号 - 蓝灯123发布时间:2022-07-18
下一篇:
Matlab并行编程方法1发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap