打印本文 打印本文 关闭窗口 关闭窗口
Object Pascal中String类型的内幕探讨
作者:武汉SEO闵涛  文章来源:敏韬网  点击数1534  更新时间:2009/4/23 18:40:47  文章录入:mintao  责任编辑:mintao
 

在Object Pascal中,String(准确的说是AnsiString)是一种可变长度的字符串,通过PChar(AString)可以将其转换为与Windows API相兼容的字符指针类型。事实上,String类型就是一个指针,你可以用Sizeof去读取它的大小,不论字符串的实际长度是多少,Sizeof(AString)永远是4。String与一般的Null-Terminated字符指针不同的是,String还要保留另外的一部分空间,用于记录字符串长度和引用计数等信息。String类型在内存中的确切格式如下:

 

(4字节)分配大小+(4字节)引用计数+(4字节)字串长度+(不定长)字符数组+(1字节)$0结束字符

 

为了验证这一点,我们可以在程序中添加一个作用域为private的String变量,在程序中动态改变它的长度和内容,同时观察它的分配大小和长度发生了什么变化。另外,为了观察引用计数的变化,只有在两个字符串互相复制的时候才能体现出来,我们在程序中也要实现这一点。

 

请新建一个Application,在窗体上放置一个Edit,一个ListBox和三个Button。其中,Edit用来改变字符串的内容;ListBox用来记录跟踪信息;三个按钮分别用于观察字符串的当前状况,观察字符串的引用计数变化情况和清空列表内容。

 

在Form的声明中添加一个变量:

type

  TForm1=class(TForm)

   ...

   private

s : string;

end;

 

添加三个按钮的事件处理如下:

procedure TForm1.Button1Click(Sender: TObject);

var

  psz : PChar;

  pdw : PDWORD;

  dw1, dw2, dw3 : DWord;

begin

  s := Edit1.Text;

  psz := PChar(s);

  pdw := PDWORD(psz);

  Dec(pdw);Dec(pdw);Dec(pdw);

  dw1 := pdw^;

  Inc(pdw);dw2 := pdw^;

  Inc(pdw);dw3 := pdw^;

  ListBox1.Items.Add( Format(''''[Current]Size:%d, Ref:%d, Len:%d'''',

                          [dw1,dw2,dw3]) );

end;

 

procedure TForm1.Button2Click(Sender: TObject);

var

  psz : PChar;

  pdw : PDWORD;

  dw1, dw2, dw3 : DWord;

  s2 : string;

  p1, p2 : Pointer;

begin

  s := Edit1.Text;

  psz := PChar(s);

  pdw := PDWORD(psz);

  Dec(pdw);Dec(pdw);Dec(pdw);

  dw1 := pdw^;

  Inc(pdw);dw2 := pdw^;

  Inc(pdw);dw3 := pdw^;

  ListBox1.Items.Add( Format(''''[Before assign]Size:%d, Ref:%d, Len:%d'''',

                         [dw1,dw2,dw3]) );

  s2 := s;

  p1 := Pointer(PChar(s));

  p2 := Pointer(PChar(s2));

  ShowMessage(Format(''''p1=%p,p2=%p'''',[p1,p2]));

  psz := pChar(s);

  pdw := PDWORD(psz);

  Dec(pdw);Dec(pdw);Dec(pdw);

  dw1 := pdw^;

  Inc(pdw); dw2 := pdw^;

  Inc(pdw); dw3 := pdw^;

  ListBox1.Items.Add( Format(''''[After assign]Size:%d, Ref:%d, Len:%d'''',

                        [dw1,dw2,dw3]) );

  s2 := s2 + ''''Another string'''';

  p1 := Pointer(PChar(s));

  p2 := Pointer(PChar(s2));

  ShowMessage(Format(''''p1=%p,p2=%p'''',[p1,p2]));

  psz := pChar(s);

  pdw := PDWORD(psz);

  Dec(pdw);Dec(pdw);Dec(pdw);

  dw1 := pdw^;

[1] [2]  下一页

打印本文 打印本文 关闭窗口 关闭窗口