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培训.期待与您交流! ---------- 函数: 什么是函数? • 函数就是定义在类中的具有特定功能的一段独立小程序. • 函数也称为方法. 函数的格 ...
随机推荐
- SilkTest天龙八部系列5-类的属性
SilkTest的面向对象机制让用户可以为类定义属性,用property语句实现.除此以外用户在类中还可以定义成员变量和不可变的setting属性.也就是是说Silktest类中可以有以下三种属性/变 ...
- [置顶] jeecg-framework-3.3.2-RELEASE 最新版本发布
平台介绍 JEECG(J2EE CodeGeneration)是一款基于代码生成器的智能开发平台,引领新开发模式(OnlineCoding模式->代码生成器模式->手工MERGE智能开 ...
- 数据类型及其空间大小,vs2012实测
#include "stdafx.h" #include <stdio.h> #include "common.h" #include " ...
- Hadoop SecondaryNameNode
[转] 1.概述 光从字面上来理解,很容易让一些初学者先入为主的认为:SecondaryNameNode(snn)就是NameNode(nn)的热备进程.X 其 实不是.snn是HDFS架构中的一 ...
- 一天一个类--ArrayList之一
今天开始打算将JDK7种的一些类的源码分析一下,笔者认为了解源码就是了解其实现过程,这是非常重要的,而不是简单的记住方法的使用,关键是了解其思想和目的这才是重要的.所以笔者决定首先将从一些容器下手.[ ...
- NET Core 以及与 .NET Framework
简析.NET Core 以及与 .NET Framework的关系 简析.NET Core 以及与 .NET Framework的关系 一 .NET 的 Framework 们 二 .NET Core ...
- 令牌桶在数据通信QoS流量监管中的应用
令牌桶(Tocken Bucket,以下简称TB)在流量监管(以下简称CAR)功能中完成对流量进行限速的作用.流量监管主要是应用与网络边缘,从而保证核心设备的正常数据处理. 在流量监管的处理过程中,首 ...
- 【Cocos2d-x游戏引擎开发笔记(25)】XML解析
原创文章,转载请注明出处:http://blog.csdn.net/zhy_cheng/article/details/9128819 XML是一种非常重要的文件格式,由于C++对XML的支持非常完善 ...
- 有关android工程的构建脚本(build.xml)的学习
学习[android-sdk-linux根目录]/tools/ant/build.xml,觉得如下几点很有用,记录之 1)ant脚本中属性值是于前置定义优化的原则,即属性发生重复定义时,前面定义的值不 ...
- linux登录windows服务器
在公司同时也兼顾了王老师会议网站的任务,我喜欢用linux,而会议网站托管在windows系统上,虽然装了双系统,但我还是比较懒,不喜欢经常切换系统.还好,linux可以实现登录windows服务器. ...