zoukankan      html  css  js  c++  java
  • String内存结构

    [delphi] view plain copy
     
    1. var  
    2.   s: AnsiString;  
    3. begin  
    4.   s := '1234567890';  
    5.   showmessage(s);  
    6. 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,表示简体中文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 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]);  
      7.   Dec(p, 2);  
      8.   ShowMessage(IntToStr(p^));  // 1  
      9.   
      10.   s2 := s;                    // 引用计数+1了  
      11.   ShowMessage(IntToStr(p^));  // 2  
      12. end;  

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

  • 相关阅读:
    【leetcode】 61. 旋转链表
    【leetcode】 55 跳跃游戏
    【leetcode 53】 最大子序和
    【leetcode】不同路径
    【leetcode】692. 前K个高频单词
    vue a标签使用@click
    函数式接口的使用
    【转】MyBatis中的collection两种使用方法
    xaf--homepage
    Windows10--设置鼠标自带光圈效果
  • 原文地址:https://www.cnblogs.com/findumars/p/7029500.html
Copyright © 2011-2022 走看看