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(251)

更多文章

http://blog.csdn.net/diligentcatrich/article/details/7594007

String 中的秘密的更多相关文章

  1. Java的String中的subString()方法

    方法如下: public String substring(int beginIndex, int endIndex) 第一个int为开始的索引,对应String数字中的开始位置, 第二个是截止的索引 ...

  2. Here String 中不该进行分词

    我们知道,在 Shell 中,一个变量在被展开后,如果它没有被双引号包围起来,那么它展开后的值还会进行一次分词(word splitting,或者叫拆词,分词这个术语已经被搜索引擎相关技术占用了)操作 ...

  3. C++string中有关字符串内容修改和替换的函数浅析

    1.assign() 原型: //string (1) basic_string& assign (const basic_string& str); //substring (2) ...

  4. 从源代码的角度聊聊java中StringBuffer、StringBuilder、String中的字符串拼接

    长久以来,我们被教导字符串的连接最好用StringBuffer.StringBuilder,但是我们却不知道这两者之间的区别.跟字符串相关的一些方法中总是有CharSequence.StringBuf ...

  5. Java-J2SE学习笔记-查找一个String中,subString的出现次数

    1.查找一个String中,subString的出现次数 2.代码 package Test; public class TestStringContain { public static void ...

  6. string中常用的函数

    string中常用的函数 发现在string在处理这符串是很好用,就找了一篇文章放在这里了.. 用 string来代替char * 数组,使用sort排序算法来排序,用unique 函数来去重1.De ...

  7. String中的==与Empty

    1.String中的==与Equals方法执行结果一样吗? 我们都知道对于引用类型"=="比较的是引用而不是具体的值,但c#中有一种神奇的叫做操作符重载的东西.官方对String类 ...

  8. Java 字符串比较,String 中的一些方法 == 和 equals 的详解

    "==" 是比较的是两个对象的内存地址,而equals方法默认情况下是比较两个对象的内存地址. 1.String str = "hello"  生成的字符串,首 ...

  9. C++从string中删除所有的某个特定字符

    C++中要从string中删除所有某个特定字符, 可用如下代码 str.erase(std::remove(str.begin(), str.end(), 'a'), str.end()); 其中, ...

随机推荐

  1. IOS某个ViewController禁止自动旋转

    IOS屏幕自动旋转,强制横竖屏方法: - (BOOL)shouldAutorotate { return YES; } - (NSUInteger)supportedInterfaceOrientat ...

  2. Ubuntu上搭建DokuWiki

    1.准备工作 1) 安装Apache sudo apt-get install apache2 2)在浏览器中输入http://localhost 如果现实It works则说明Apache安装成功, ...

  3. VirtualBox虚拟机安装RedHat7.3编译Linux0.01内核

    引子 由于需要编译linux0.01内核,而目前的linux版本太高需要降低gcc版本等等,需要做不少调整非常不方便. 所以,直接安装RedHat7.3,这样就好编译linux0.01的内核了. 但是 ...

  4. 如何自学 Python(干货合集)

    http://wenku.baidu.com/view/5108f974192e45361066f583.html

  5. asp.net上传控件使用

    protected void Button1_Click(object sender, EventArgs e) { string str = ""; if (FileUpload ...

  6. SICP中sqrt(开方)的实现(附C#实现)

    #lang racket (define (square x) (* x x)) (define (sqrt-iter guess x) (if (good-enough? guess x) gues ...

  7. HEVC码率控制浅析——HM代码阅读之一

    HM的码率控制提案主要参考如下三篇:K0103,M0036,M0257.本文及后续文章将基于HM12.0进行讨论,且首先仅讨论K0103对应的代码,之后再陆续补充M0036,M0257对应的代码分析, ...

  8. java.lang.NoClassDefFoundError: org/apache/lucene/analysis/synonym/SynonymFilter

    2013-6-24 13:28:51 org.apache.solr.common.SolrException log 严重: java.lang.NoClassDefFoundError: org/ ...

  9. hdu1172猜数字

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1172 题目 猜数字 Time Limit: 20000/10000 MS (Java/Others) ...

  10. mysql导入sql文件过大或连接超时的解决的方法

    前段时间出差在现场开发的时候,导入数据库老是出问题.最后发现了一个奇妙sql语句交给实施,仅仅要导入出错就把例如以下语句运行就能够了.至今屡试不爽. set global max_allowed_pa ...