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. 彻底理解浮动float CSS浮动详解 清除浮动的方法

    我们把网页的常用的布局格式分为以下三种: 1.标准流. 所谓的标准流就是,行内元素自己单独一行,而块级元素是上下显示的. 以前我们学习的都是标准流.   注意:标准流使我们网页布局中最稳定的一种结构 ...

  2. pojg487-3279电话号码转换(字符映射)

    http://poj.grids.cn/practice/2974 注意输入中连字符可以任意添加和删除. 描述企业喜欢用容易被记住的电话号码.让电话号码容易被记住的一个办法是将它写成一个容易记住的单词 ...

  3. Android大放送干:书籍、过程、工具等各种全

    完全干燥分享,本文收集Android制定必要的书籍.过程.具.新闻和杂志各种资源.它们能让你在Android开发之旅的各个阶段都受益. 入门 <Learning Android(中文版)> ...

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

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

  5. Reverse Words in a String | LeetCode OJ | C++

    我的思路:先读取每一个单词,存放到容器中:读取完毕后,将容器中的单词倒序写入输出中. #include<iostream> #include<string> #include& ...

  6. C语言,链表反转

    倒序思路:依次把后面的节点移往头部. struct Node{ struct Node* next; int data; }; typedef struct Node NODE; NODE* inve ...

  7. Source Insight使用技巧

    1. source insight必设: option-->key assignments-->    Edit: Delete Line ---- Assign New Key: Ctr ...

  8. Android之ksoap2-android详解与调用天气预报Webservice完整实例

    Google为Android平台开发Web Service客户端提供了ksoap2-android项目,在这个网址下载开发包http://code.google.com/p/ksoap2-androi ...

  9. java Native 方法

    一. 什么是Native Method   简单地讲,一个Native Method就是一个java调用非java代码的接口.一个Native Method是这样一个java的方法:该方法的实现由非j ...

  10. Bootstrap技术: 模式对话框的使用

    一.概述 说到模式对话框,大家肯定都会想到windows下GUI程序,在gui程序中,有大量的对话框. 在web程序中,随着页面交互式功能的增多,有很多场景下也会用到对话框.在html原生的支持下,有 ...