变量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. CMake初步(2)

    转自:<你所不知的OSG>第一章:CMake初步(2) http://bbs.osgchina.org/forum.php?mod=viewthread&tid=1229& ...

  2. C++ 中dynamic_cast&lt;&gt;的用法

    /*这是从网上摘下的样例,主要讲述了 dynamic_cast<> 的用法.*/ /* 作用:将一个基类对象指针(或引用)cast到继承类指针,dynamic_cast会依据基类指针是否真 ...

  3. 谁能告诉我war包的作用及使用方法。。。。。。

    链接地址:http://zhidao.baidu.com/link?url=iliyTcmsTKb1K4gHMtWUsRIBaXglyOKIQsWwdrgvydvnaUHLe0KEoHvLVz8tLY ...

  4. java--内部类实现“类的多重继承”

    class Fa1{ private int k = 1; void show() { System.out.println(k); } } class Fa2{ private int k = 10 ...

  5. 03-IOSCore - XML及解析、Plist

    一.XML 可扩展标记语言 是什么?是一段有规范的字符串, 用在哪?用在任何地方 语法: * 结点Node <结点名 属性名="属性值"> 结点内容 </结点名& ...

  6. Jquery学习笔记:操作form表单元素之一(文本框和下拉框)

    一.概述 在web页面开发中,经常需要获取和设置表单元素的值(如文本框中的内容),特别是在ajax应用中,更是常态.本文系统的介绍下如何操作. 同操作其它html元素一样,操作的过程差不多. 第一步, ...

  7. Hadoop 源码分析(二四)FSNamesystem

    以下轮到FSNamesystem 出场了. FSNamesystem.java 一共同拥有4573 行.而整个namenode 文件夹下全部的Java 程序总共也仅仅有16876 行,把FSNames ...

  8. BZOJ 1264: [AHOI2006]基因匹配Match( LCS )

    序列最大长度2w * 5 = 10w, O(n²)的LCS会T.. LCS 只有当a[i] == b[j]时, 才能更新答案, 我们可以记录n个数在第一个序列中出现的5个位置, 然后从左往右扫第二个序 ...

  9. QString与中文,QString与std::wstring的相互转换(使用fromStdWString和u8关键字)

    Qt版本:5.5.1 Qt的QString功能丰富,对非英语语言的支持也不是问题,但支持得不够直接.例如,像 ? 1 QString str("死亡使者赛维"); 这样直接用带中文 ...

  10. perl中 wx返回的json需要encode_utf8($d);

    $count is 9 now not support message 51 Wide character in print at /root/scanwx/lib/synccheck.pm line ...