Delphi字符串与引用计数
Delphi使用带字符串的引用计数 这是否意味着“1234567890”只有一个内存分配 所有的a,b,c,d,e和f.s都提到它了吗Delphi字符串与引用计数,delphi,string,reference,memory-management,Delphi,String,Reference,Memory Management,Delphi使用带字符串的引用计数 这是否意味着“1234567890”只有一个内存分配 所有的a,b,c,d,e和f.s都提到它了吗 type TFoo = class s: string; end; const a = '1234567890'; b = a; c : string = a; var d: string; e: string; f: TFoo; function GetStr1(co
type
TFoo = class
s: string;
end;
const
a = '1234567890';
b = a;
c : string = a;
var
d: string;
e: string;
f: TFoo;
function GetStr1(const s: string): string;
begin
Result := s;
end;
function GetStr2(s: string): string;
begin
Result := s;
end;
begin
d := GetStr1(b);
e := GetStr2(c);
f := TFoo.Create;
f.s := a;
end;
是的,字符串是ref计数的,只有通过变量修改内容时才会创建副本(写时复制语义),更多信息请参见: 对以下部件进行少量添加: 当在代码中调用
UniqueString()
时,当字符串中的字符被[]
访问时,以及当字符串类型转换为PChar
时,也将创建副本。即使当只读取PChar
和字符串元素时,也会发生这种情况
了解如何从可能共享的字符串强制使用唯一字符串很重要,因为有些Windows API函数不能使用只读字符指针调用,而字符串常量的
PChar
就是只读字符指针。在这种情况下,需要首先将常量复制到变量,因此强制转换它将返回指向可写内存的PChar
。是的,在特定示例中只有一个分配。如果您使用了UniqueString
,如mghie所说,或者如果您动态构建了字符串,那么即使字符串内容与其他字符串相同,您也会得到一个新的字符串分配
但是,关于您的特定示例,有一个有趣的事实:实际上根本没有为字符串“1234567890”分配内存。字符串常量的数据存储在磁盘上的可执行映像中,并在代码访问它时由操作系统分页。它占用内存地址空间,作为整个可执行模块内存映射的一部分,但由于它由磁盘上的原始可执行文件支持,因此它不构成进程提交内存的一部分,也不需要在页面文件中进行备份
例如,此程序将在运行时报告访问冲突:
{$apptype console}
uses SysUtils;
const
s = '1234567890';
procedure Change(const r: string);
var
p: PChar;
begin
p := PChar(r);
p^ := 'x';
end;
begin
try
Change(s);
except
on e: Exception do
Writeln(e.Message);
end;
end.
好提示。因此,当函数返回字符串时,smart Delphi不会丢失引用。“WideString的行为与AnsiString完全相同;它是自动管理的,以null结尾,并对引用计数”->WideString的不进行引用计数!这是错的吗?来自RADStudio“WideString类型表示动态分配的16位Unicode字符字符串。在某些方面,它类似于AnsiString。在Win32上,WideString与COM BSTR类型兼容。WideString适合在COM应用程序中使用。但是,WideString不使用引用计数,因此UnicodeString在其他类型的应用程序中更灵活、更高效。“是的。我注意到,当我使用返回数据的PChar参数调用dll函数时:-((注意,如果启用“使用调试DCU”,则可以跟踪代码,包括帮助程序)如果我声明const s:string='1234567890',则不会引发访问冲突?(我现在无法测试它)const s:string='…在Delphi 7中没有区别。编译器调用System._LStrLAsg(var dest;const source)它将dest设置为指向常量。但是,如果dest字符串是全局的,则编译器将调用System.\u LStrAsg。源代码指出,这样做是为了与DLL兼容。