Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi字符串与引用计数_Delphi_String_Reference_Memory Management - Fatal编程技术网

Delphi字符串与引用计数

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

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(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兼容。