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

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

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

String内存结构的更多相关文章

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

    变量s的内存结构为(字符串编码)A8 03 (字符宽度)01 00 (引用计数)FF FF FF FF (字符串长度)0A 00 00 00 (实际内容)31 32 33 34 35 36 37 38 ...

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

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

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

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

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

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

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

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

  6. Java中的OutOfMemoryError的各种情况及解决和JVM内存结构

    在JVM中内存一共有3种:Heap(堆内存),Non-Heap(非堆内存) [3]和Native(本地内存). [1] 堆内存是运行时分配所有类实例和数组的一块内存区域.非堆内存包含方法区和JVM内部 ...

  7. 浅析JVM内存结构和6大区域(转)

    其实对于我们一般理解的计算机内存,它算是CPU与计算机打交道最频繁的区域,所有数据都是先经过硬盘至内存,然后由CPU再从内存中获取数据进行处理,又将数据保存到内存,通过分页或分片技术将内存中的数据再f ...

  8. Java内存结构、类的初始化、及对象构造过程

    概述 网上关于该题目的文章已经很多,我觉得把它们几个关联起来讲可能更好理解一下.与其它语言一样,它在执行我们写的程序前要先分配内存空间,以便于存放代码.数据:程序的执行过程其实依然是代码的执行及数据的 ...

  9. JVM内存结构、垃圾回收那点事(转)

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

随机推荐

  1. SendMessageTimeout 的使用

    在WINDOW编程中,发送消息的常用API有SendMessage,PostMessage,PostThreadMessage. 一般每个线程有两个队列:一个用来接收通过Send函数的消息,另外一个队 ...

  2. style.height、offsetHeight、clientHeight、scrollHeight的差别

    style.height 包含元素的滚动栏,不包含边框 clientHeight 不包含元素的滚动栏和边框 offsetHeight 包含元素的滚动栏和边框 scrollHeight offsetHe ...

  3. Spring学习笔记之六(数据源的配置)

    1.前言 上一篇博客分析了,Spring中实现AOP的两种动态代理的机制,以下这篇博客.来解说一下Spring中的数据源的配置.  2.DAO支持的模板类 Spring提供了非常多关于Dao支持的模板 ...

  4. sql中group by用来干嘛的

    sql中group by用来干嘛的 一.总结 一句话总结: 1.group by用来分类汇总的,by后面接要分的类 2.group by既然是分类汇总,那就要和聚合函数结合使用,因为要汇总啊 3.ha ...

  5. BootstrapTable的使用教程

    官方网站:http://bootstrap-table.wenzhixin.net.cn/参考文档:http://issues.wenzhixin.net.cn/bootstrap-table/ind ...

  6. 【a802】最少转弯问题

    Time Limit: 10 second Memory Limit: 2 MB 问题描述 给出一张地图,这张地图被分为n*m(n,m<=100)个方块,任何一个方块不是平地就是高山.平地可以通 ...

  7. UIApplicationsharedApplication的详解

    iPhone应用程序是由主函数main启动,它负责调用UIApplicationMain函数,该函数的形式如下所示: int UIApplicationMain ( int argc, char *a ...

  8. XMPP之ios即时通讯客户端开发-mac上搭建openfire服务器(二)

    come from:http://www.cnblogs.com/xiaodao/archive/2013/04/05/3000554.html 一.下载并安装openfire 1.到http://w ...

  9. WIN内核线程池函数

    线程池 (本章节中样例都是用 VS2010 编译调试的) 线程池编写必须在 Windows Vista 操作系统(以及以上版本号的操作系统)下,且 C++ 编译器版本号至少是 VS2008 线程池的功 ...

  10. 关于Dagger 2的文章汇总

    首先是我真正看懂了的第一篇文章 代码GG之家的 Dagger2图文详解 这篇文章很直接,还配有代码demo.至少我是看懂了. Dagger2 使用详解 这篇文章同样配有demo,同时文末还有很多有用的 ...