关于AnsiString使用的菜鸟问题 ( 积分: 50 )

  • 主题发起人 主题发起人 justinfoo
  • 开始时间 开始时间
J

justinfoo

Unregistered / Unconfirmed
GUEST, unregistred user!
请问:ShortString类型的变量的第一个字节存放的是该变量的实际长度。例如:

var
shortStr: ShortString;
begin
shortStr:= 'I have';
ShowMessage(shortStr[0])
{ 显示的是 '-',因为S[0]存放的是#6,即共有6个字符 }
end;

那么AnsiString类型的变量的第一个字节存放的又是什么东西呢?例如:

var
ansiStr: AnsiString;
vWhatIsStored: Variant;
begin
SetLength(ansiStr, 6);
ansiStr:= 'I have';
vWhatIsStored:= ansiStr[0]
{ 事实上,此行编译报错:Element 0 inaccessible - use 'Length' or 'SetLength' }
ShowMessage(VarToStr(vWhatIsStored))
{ 假设编译不报错,显示的会是什么呢?或者说,存放的又是什么呢?莫非根本就没开辟ansiStr[0]这个内存区域?高手赐教! }
end;
 
请问:ShortString类型的变量的第一个字节存放的是该变量的实际长度。例如:

var
shortStr: ShortString;
begin
shortStr:= 'I have';
ShowMessage(shortStr[0])
{ 显示的是 '-',因为S[0]存放的是#6,即共有6个字符 }
end;

那么AnsiString类型的变量的第一个字节存放的又是什么东西呢?例如:

var
ansiStr: AnsiString;
vWhatIsStored: Variant;
begin
SetLength(ansiStr, 6);
ansiStr:= 'I have';
vWhatIsStored:= ansiStr[0]
{ 事实上,此行编译报错:Element 0 inaccessible - use 'Length' or 'SetLength' }
ShowMessage(VarToStr(vWhatIsStored))
{ 假设编译不报错,显示的会是什么呢?或者说,存放的又是什么呢?莫非根本就没开辟ansiStr[0]这个内存区域?高手赐教! }
end;
 
做一下试验不就知道了`~
 
编译出错的,早试过了。
 
从Delphi字符串(AnsiString)的内存管理机制来讲,ansiStr[0]并不能代表什么东西,因为它是属于字符串数据前面的两个32位管理数据中的一个字节。这两个管理数据的前面那个表示字符串的长度,后面那个表示字符串的“引用计数”(引用计数指这个字符串被引用了多少次)。这两个管理数据都是32位(4个字节)的无符号整数。因此所谓的ansiStr[0]实际上就是字符串的“引用计数”数据值存储单元的最后一个字节。以ansiStr:= 'I have';为例,这个字符串在内存中的映像如下:
-7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6
┃ ┃ ┃ ┃ I ' ' h a v e
┗字符串长度┛ ┗引用计数━┛ ┃


ansiStr
 
授之与鱼,不如授之与渔.
to SparKV,我想知道,你是怎么知道的,是课本上的东西吗,还是有什么工具可以观察到内存映像,谢谢.
 
我的上述认识来自我们大家每天都会用到的Delphi 自己的帮助文档,打开Delphi 的Help,在“索引”里面输入“Long strings”就可以查到这个主题了。
 
AnsiString, also called a long string, represents a dynamically allocated string whose maximum length is limited only by available memory. It uses 8-bit ANSI characters.
A long-string variable is a pointer occupying four bytes of memory. When the variable is empty—that is, when it contains a zero-length string—the pointer is nil and the string uses no additional storage. When the variable is nonempty, it points to a dynamically allocated block of memory that contains the string value, a 32-bit length indicator, and a 32-bit reference count. This memory is allocated on the heap, but its management is entirely automatic and requires no user code.

Because long-string variables are pointers, two or more of them can reference the same value without consuming additional memory. The compiler exploits this to conserve resources and execute assignments faster. Whenever a long-string variable is destroyed or assigned a new value, the reference count of the old string (the variable’s previous value) is decremented and the reference count of the new value (if there is one) is incremented
if the reference count of a string reaches zero, its memory is deallocated. This process is called reference-counting. When indexing is used to change the value of a single character in a string, a copy of the string is made if—but only if—its reference count is greater than one. This is called copy-on-write semantics.
 
后退
顶部