变量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并未作出优化
下面的代码就可以说明问题,两次显示的字符串内存地址不同。

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

接着看看下面的代码

  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的内存结构后,我们就可以通过代码来观测引用计数的值了

    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. s2 := s;                    // 引用计数+1了
    10. ShowMessage(IntToStr(p^));  // 2,引用计数为2
    11. end;

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

Delphi的String内存结构(够清楚) good的更多相关文章

  1. String内存结构

    var s: AnsiString; begin s := '1234567890'; showmessage(s); end; 变量s的内存结构为A8 03 01 00 FF FF FF FF 0A ...

  2. Delphi XE7中各种字符串与字符类型的内存结构

    1. ShortString 类型 定义:type ShortString = string[255]; 内存结构与大小:ShortString 是每个字符为单字节的字符串.ShortString 的 ...

  3. Delphi中String类型原理介绍

    Delphi中字符串的操作很简单,但幕后情况却相当复杂.Pascal传统的字符串操作方法与Windows不同,Windows吸取了C语言的字符串操作方法.32位Delphi中增加了长字符串类型,该类型 ...

  4. delphi dispose释放内存的方法 New 和 GetMem 的区别

    来自:http://blog.sina.com.cn/s/blog_4bc47d2301018trf.html -------------------------------------------- ...

  5. jvm内存结构及对象漫谈(较全)

    最近想整理一下GC相关的知识和经验,在整理之前先整理一下jvm的内存结构,后续会持续更新. jvm内存结构重要由两部分组成:线程共享区域与线程私有区域,如下图所示: 其中方法区和堆为线程共享区域,栈与 ...

  6. UNDO内存结构剖析

    UNDO内存结构剖析 一.场景 Oracle的 C事物从早上9:00开始读取A表全部10w行数据,这个而读取需要经历5分钟.在9:01的时候,B事物将A表删除100条记录,那么,当9:05的时候,事物 ...

  7. 浅析JVM内存结构和6大区域(转)举例非常好

    内存作为系统中重要的资源,对于系统稳定运行和高效运行起到了关键的作用,Java和C之类的语言不同,不需要开发人员来分配内存和回收内存,而是由JVM来管理对象内存的分配以及对象内存的回收(又称为垃圾回收 ...

  8. JVM内存结构、垃圾回收那点事

    翻看电脑的文件夹,无意看到了9月份在公司做的一次分享,浏览了一下"婆婆特",发现自己在ppt上的写的引导性问题自己也不能确切的回答出来,哎,知识这东西,平时不常用的没些日子就生疏了 ...

  9. 黑马程序员——JAVA基础之函数,重载,内存结构

      ------- android培训.java培训.期待与您交流! ---------- 函数: 什么是函数? • 函数就是定义在类中的具有特定功能的一段独立小程序. • 函数也称为方法. 函数的格 ...

随机推荐

  1. Elven Postman(二叉树)

    Elven Postman Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  2. javascript 动态推断html元素

    在javascript中为了针对不同的元素运行不同的操作,须要在javascript中对触发事件的元素进行推断,然后运行不同的操作. 样例: html <input type='button' ...

  3. 基于SOAP的xml网络交互心得

    感谢小二同学将遇到的问题分享给我们,再此给以掌声.如果看不懂下面文章的建议查找一下HTTP协议的文艺,对HTTP协议要有个概念. XML网络交互心得 目录 一.     xml解析 1.根路径下 2. ...

  4. 用shell脚本爬取网页信息

    有个小需求,就是爬取一个小网站一些网页里的某些信息,url是带序号的类似的,不需要写真正的spider,网页内容也是差不多的 需要取出网页中<h1></h1>中间的字符串,而且 ...

  5. 使用gettimeofday测试函数运行的时间

    #include <time.h> #include <stdio.h> #include<sys/time.h> #define NEW_TIME_VALE st ...

  6. HDOJ 3047 带权并查集

    解题思路转自: http://blog.csdn.net/azheng51714/article/details/8500459 http://blog.csdn.net/acresume/artic ...

  7. WPF4字体改善

    原文 WPF4字体改善 WPF4对字体渲染做了很大的改善,增加了TextOptions属性,该属性可以设置TextFormattingMode,TextRenderingMode,TextHintin ...

  8. BNU Box of Bricks

    http://www.bnuoj.com/bnuoj/problem_show.php?pid=1596 这个题一开始以为要求最少移动次数,把我吓到了,原来只要求最少移动几个方块就行了..这一下就变简 ...

  9. 通过demo搞懂encode_utf8和decode_utf8

    perl 编码问题: use utf8表示代码使用UTF-8写的 [root@wx03 0710]# cat a1.pl #use utf8; my $str='测试utf8字符集'; print $ ...

  10. sharepoint 2013 根据网站模版创建网站,并赋值网站权限 create a site by custom site template

    通过程序,根据网站模版,创建新的网站 private void CreateSiteBySiteTemplate() { SPSecurity.RunWithElevatedPrivileges(de ...