Delphi的String内存结构(够清楚) good
变量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并未作出优化
下面的代码就可以说明问题,两次显示的字符串内存地址不同。
- procedure Foo();
- var
- s: AnsiString;
- begin
- s := '1234567890';
- ShowMessage(IntToHex(Integer(@s[1]), 8));
- end;
- procedure TForm1.Button1Click(Sender: TObject);
- var
- s: AnsiString;
- begin
- s := '1234567890';
- ShowMessage(IntToHex(Integer(@s[1]), 8));
- Foo;
- end;
接着看看下面的代码
- var
- s: AnsiString;
- begin
- s := Caption;
- ShowMessage(IntToHex(Integer(@s[1]), 8));
- end;
由于没有使用常量字符串,所以引用计数不再是-1
(代码页)A8 03 (字符宽度)01 00 (引用计数是1)01 00 00 00 (字符串长度)05 00 00 00 (字符内容)46 6F 72 6D 31 (结束符)00
在知道了string的内存结构后,我们就可以通过代码来观测引用计数的值了
- var
- s, s2: AnsiString;
- p: ^Integer;
- begin
- s := Caption;
- p := Pointer(@s[1]); // 应该是得到s[1]的地址,即第一个字符的地址
- Dec(p, 2); // 前移2个单位(8个字节,因为每个^integer类型的数据长度是4)
- ShowMessage(IntToStr(p^)); // 1,引用计数为1
- s2 := s; // 引用计数+1了
- ShowMessage(IntToStr(p^)); // 2,引用计数为2
- end;
http://blog.csdn.net/aqtata/article/details/38905387
Delphi的String内存结构(够清楚) good的更多相关文章
- String内存结构
var s: AnsiString; begin s := '1234567890'; showmessage(s); end; 变量s的内存结构为A8 03 01 00 FF FF FF FF 0A ...
- Delphi XE7中各种字符串与字符类型的内存结构
1. ShortString 类型 定义:type ShortString = string[255]; 内存结构与大小:ShortString 是每个字符为单字节的字符串.ShortString 的 ...
- Delphi中String类型原理介绍
Delphi中字符串的操作很简单,但幕后情况却相当复杂.Pascal传统的字符串操作方法与Windows不同,Windows吸取了C语言的字符串操作方法.32位Delphi中增加了长字符串类型,该类型 ...
- delphi dispose释放内存的方法 New 和 GetMem 的区别
来自:http://blog.sina.com.cn/s/blog_4bc47d2301018trf.html -------------------------------------------- ...
- jvm内存结构及对象漫谈(较全)
最近想整理一下GC相关的知识和经验,在整理之前先整理一下jvm的内存结构,后续会持续更新. jvm内存结构重要由两部分组成:线程共享区域与线程私有区域,如下图所示: 其中方法区和堆为线程共享区域,栈与 ...
- UNDO内存结构剖析
UNDO内存结构剖析 一.场景 Oracle的 C事物从早上9:00开始读取A表全部10w行数据,这个而读取需要经历5分钟.在9:01的时候,B事物将A表删除100条记录,那么,当9:05的时候,事物 ...
- 浅析JVM内存结构和6大区域(转)举例非常好
内存作为系统中重要的资源,对于系统稳定运行和高效运行起到了关键的作用,Java和C之类的语言不同,不需要开发人员来分配内存和回收内存,而是由JVM来管理对象内存的分配以及对象内存的回收(又称为垃圾回收 ...
- JVM内存结构、垃圾回收那点事
翻看电脑的文件夹,无意看到了9月份在公司做的一次分享,浏览了一下"婆婆特",发现自己在ppt上的写的引导性问题自己也不能确切的回答出来,哎,知识这东西,平时不常用的没些日子就生疏了 ...
- 黑马程序员——JAVA基础之函数,重载,内存结构
------- android培训.java培训.期待与您交流! ---------- 函数: 什么是函数? • 函数就是定义在类中的具有特定功能的一段独立小程序. • 函数也称为方法. 函数的格 ...
随机推荐
- Android常用动画Animation的使用
Andriod中有几种常用的Animation AlphaAnimation 淡入淡出效果 RotateAnimation 旋转效果 ScaleAnimation 缩放动画 TranslaAnima ...
- NodeJS用Express建立project
1.通过下面命令建立站点基本结构: <span style="margin: 0px; padding: 0px; font-family: Verdana, Arial, Helve ...
- Linux下tcpdump用法
根据使用者的定义对网络上的数据包进行截获的包分析工具.tcpdump将网络中传送的数据包的“头”完全截获下来提供分析.它支持针对网络层.协议.主机.网络或端口的过滤,并提供了and. or.not等逻 ...
- QSerialPort
(草稿) qt5提供QSerialPort类,封装了串口的api, 可以用这个类写串口通信程序.
- SecureCRT辅助解决方案
SecureCRT辅助解决方案 1. 下载SecureCRT 7.3版本并激活: 2. SecureCRT linux配色方案: 3. SecureCRT设置log保存方案: 1. secureCRT ...
- webform--常用的控件
一.简单控件 1.Lable——标签:在网页中呈现出来的时候会变成span标签 属性:Text——标签上的文字 BackColor,ForeColor——背景色,前景色 Font——字体 Bold- ...
- 高级UIKit-07(AVAudioPlayer)
[day09-1-AVAudioPlayer]:播放音乐案例 实现多媒体需要准备以下两点: 需要引入一个框架AVFoundation.framework 然后引入#import <AVFound ...
- Codeforces Round #272 (Div. 2)AK报告
A. Dreamoon and Stairs time limit per test 1 second memory limit per test 256 megabytes input standa ...
- BZOJ 1257: [CQOI2007]余数之和sum( 数论 )
n >= k 部分对答案的贡献为 k * (n - k) n < k 部分贡献为 ∑ (k - ⌊k / i⌋ * i) = ∑ , ⌊k / i⌋ 相等的数是连续的一段, 此时这段连 ...
- 2783: [JLOI2012]树( dfs + BST )
直接DFS, 然后用set维护一下就好了.... O(nlogn) ------------------------------------------------------------------ ...