String 中的秘密
|
Navigation: 数据类型相关 > Delphi 的字符及字符串 > [3] - String 中的秘密 |
|
//String 的指针地址及实际的内存地址
var
str: string;
pstr: PString;
pc: PChar;
begin
{在没有给 str 赋值以前, 既然声明了, 就有了指针地址(@str):}
ShowMessage(IntToStr(Integer(@str))); {1244652; 这是在栈中的 str 的指针地址}
{但现在还没有分配真正储存字符串内存}
ShowMessage(IntToStr(Integer(str))); {0; 0 就是 null}
str := 'Delphi';
{一旦赋值后...}
ShowMessage(IntToStr(Integer(@str))); {1244652; 这是在栈中的 str 的指针地址}
ShowMessage(IntToStr(Integer(str))); {4580800; 这是在堆中的 str 的实际地址}
{通过指针地址获取字符串, 其中的 pstr 是前面定义的字符串指针}
pstr := @str;
ShowMessage(pstr^); {Delphi}
{通过实际地址获取字符串, 其中的 pc 是前面定义的字符指针}
pc := PChar(Integer(str));
ShowMessage(pc); {Delphi}
end;
--------------------------------------------------------------------------------
一个字符串(AnsiString 或 String, 譬如是 "Form1" )在内存中是这样储存的:
黄色区域是真正存字符串的位置, 前面说的字符串所在的内存地址, 就是本例中的 "F" 所在的位置;
蓝色的四个字节储存一个 Integer 值, 表示字符串的长度;
最后红色的一个字节储存一个空字符(#0), 表示字符串的结束, 同时也是为了和 Windows 的 null 结束的字符串兼容;
绿色的四个字节也是一个 Integer 值, 表示该字符串被引用的次数(也就是有几个字符串的指针指向它).
还是看例子吧:
--------------------------------------------------------------------------------
var
str,s1,s2: string;
pint: PInteger;
begin
str := Self.Text; {把窗体标题给它吧; 现在 str 指向了窗体标题所在的内存位置}
s1 := str; {给 s1 赋值}
s2 := str; {给 s2 赋值; 现在窗体标题已经有了 str、s1、s2 三个引用}
{str、s1、s2 的指针肯定不一样; 但现在指向内存的同一个位置, 测试:}
ShowMessage(IntToStr(Integer(str))); {15190384}
ShowMessage(IntToStr(Integer(s1))); {15190384}
ShowMessage(IntToStr(Integer(s2))); {15190384}
{向左偏移 4 个字节就是字符串长度的位置, 读出它来(肯定是5):}
pint := PInteger(Integer(str) - 4);
ShowMessage(IntToStr(pint^)); {5}
{向左偏移 8 个字节就是字符串的引用计数, 读出它来(肯定是3):}
pint := PInteger(Integer(str) - 8);
ShowMessage(IntToStr(pint^)); {3}
end;
--------------------------------------------------------------------------------
当某段字符串内存的引用计数为 0 时, Delphi 就会自动释放它; 这也是字符串不需要手动释放的原因.
我在测试时发现: 所有常量和非全局的变量的引用计数一直是 "-1".
--------------------------------------------------------------------------------
我的同类文章
- •使用Delphi命名空间2016-01-13阅读29
- •Delphi编码规范2014-07-28阅读308
- •减小Delphi的Exe文件大小2014-06-15阅读292
- •一个简单的反射连接程序2014-04-25阅读239
- •Sdk Manager.exe 闪退问题的解决2014-02-14阅读371
- •Delphi资源2015-04-09阅读285
- •Delphi如果要追赶C#,最应该做的2014-07-28阅读362
- •DelphiXe5中的双向绑定2014-04-26阅读277
- •Delphi中的TreeView2014-02-18阅读295
- •Delphi中拖动无边框窗口的5种方法2014-01-12阅读438
- http://blog.csdn.net/diligentcatrich/article/details/7594007
String 中的秘密的更多相关文章
- Java的String中的subString()方法
方法如下: public String substring(int beginIndex, int endIndex) 第一个int为开始的索引,对应String数字中的开始位置, 第二个是截止的索引 ...
- Here String 中不该进行分词
我们知道,在 Shell 中,一个变量在被展开后,如果它没有被双引号包围起来,那么它展开后的值还会进行一次分词(word splitting,或者叫拆词,分词这个术语已经被搜索引擎相关技术占用了)操作 ...
- C++string中有关字符串内容修改和替换的函数浅析
1.assign() 原型: //string (1) basic_string& assign (const basic_string& str); //substring (2) ...
- 从源代码的角度聊聊java中StringBuffer、StringBuilder、String中的字符串拼接
长久以来,我们被教导字符串的连接最好用StringBuffer.StringBuilder,但是我们却不知道这两者之间的区别.跟字符串相关的一些方法中总是有CharSequence.StringBuf ...
- Java-J2SE学习笔记-查找一个String中,subString的出现次数
1.查找一个String中,subString的出现次数 2.代码 package Test; public class TestStringContain { public static void ...
- string中常用的函数
string中常用的函数 发现在string在处理这符串是很好用,就找了一篇文章放在这里了.. 用 string来代替char * 数组,使用sort排序算法来排序,用unique 函数来去重1.De ...
- String中的==与Empty
1.String中的==与Equals方法执行结果一样吗? 我们都知道对于引用类型"=="比较的是引用而不是具体的值,但c#中有一种神奇的叫做操作符重载的东西.官方对String类 ...
- Java 字符串比较,String 中的一些方法 == 和 equals 的详解
"==" 是比较的是两个对象的内存地址,而equals方法默认情况下是比较两个对象的内存地址. 1.String str = "hello" 生成的字符串,首 ...
- C++从string中删除所有的某个特定字符
C++中要从string中删除所有某个特定字符, 可用如下代码 str.erase(std::remove(str.begin(), str.end(), 'a'), str.end()); 其中, ...
随机推荐
- 深入理解GCD ( 二 )
转自@nixzhu的GitHub主页(译者:Riven.@nixzhu),原文<Grand Central Dispatch In-Depth: Part 2/2> 欢迎来到GCD深入理解 ...
- UVA 10020 Minimal coverage(贪心 + 区间覆盖问题)
Minimal coverage The Problem Given several segments of line (int the X axis) with coordinates [Li, ...
- C-KMP
一.BF算法 --传统算法 BF算法是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串P的第一个字符进行匹配,若相等,则继续比较S的第二个字符和P的第二个字符:若不相等,则比较S的 ...
- Android Mediaplayer 调用release()的时候ANR
先stop,然后再release,最后吧media置为null
- stringstream clear()的疑问 - yuanshuilee的日志 - 网易博客
stringstream clear()的疑问 - yuanshuilee的日志 - 网易博客 stringstream clear()的疑问 2013-09-05 08:43:13| 分类: ...
- hive怎样处理多分隔符数据
问题描写叙述: 大数据维稳需求中,客户提供的測试数据为多个字符做分隔符('|#'),在pig中会直接报错,hive中仅仅认第一个分隔符. 因为数据量比較大(160G),在文本中替换成单个字符分 ...
- 20款Notepad++插件下载和介绍
转自:http://www.kuqin.com/developtool/20090628/59334.html Notepad++从3.4版本开始支持插件机制,让用户可选择的为本身已经优秀的Notep ...
- debian网易163更新服务器 源
sudo vi /etc/apt/sources.list 加入如下内容即可: deb http://mirrors.163.com/debian/ jessie main non-free cont ...
- perl malformed JSON string, neither tag, array, object, number, string or atom, at character offset
[root@wx03 ~]# cat a17.pl use JSON qw/encode_json decode_json/ ; use Encode; my $data = [ { 'name' = ...
- Python中使用Flask、MongoDB搭建简易图片服务器
主要介绍了Python中使用Flask.MongoDB搭建简易图片服务器,本文是一个详细完整的教程,需要的朋友可以参考下 1.前期准备 通过 pip 或 easy_install 安装了 pymong ...