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
String Delphi对字符串的写拷贝_String_Delphi - Fatal编程技术网

String Delphi对字符串的写拷贝

String Delphi对字符串的写拷贝,string,delphi,String,Delphi,我有这样一个代码: function Test: string; var r, s: string; begin r := 'Hello'; Writeln(NativeInt(PChar(@r[1]))); s := r; Writeln(NativeInt(PChar(@s[1]))); Result := r; Writeln(NativeInt(PChar(@Result[1]))); end; 人们说delphi对字符串使用写时复制。但是上面

我有这样一个代码:

function Test: string;
var
   r, s: string;
begin
   r := 'Hello';
   Writeln(NativeInt(PChar(@r[1])));
   s := r;
   Writeln(NativeInt(PChar(@s[1])));
   Result := r;
   Writeln(NativeInt(PChar(@Result[1])));
end;

人们说delphi对字符串使用写时复制。但是上面的函数为变量r、s和Result打印3个不同的地址。所以这很令人困惑。。内存中是否只有“Hello”字符串的副本?

每当您获取字符串中某个元素的地址时,在编译器眼中,该元素被视为写入。就它而言,您现在有了一个指向字符串内部的原始指针,谁知道您打算用它做什么。因此,从它的角度来看,它是安全的。它决定创建字符串的唯一副本,以便您可以自由地使用原始指针执行任何卑鄙的操作

您编译的代码如下所示:

Project2.dpr.13: r := 'Hello'; 00419EF8 8D45FC lea eax,[ebp-$04] 00419EFB BAA89F4100 mov edx,$00419fa8 00419F00 E827D2FEFF call @UStrLAsg Project2.dpr.14: Writeln(NativeInt(PChar(@r[1]))); 00419F05 8D45FC lea eax,[ebp-$04] 00419F08 E883D3FEFF call @UniqueStringU 00419F0D 8BD0 mov edx,eax 00419F0F A18CE64100 mov eax,[$0041e68c] 00419F14 E853B2FEFF call @Write0Long 00419F19 E82EB5FEFF call @WriteLn 00419F1E E845A1FEFF call @_IOTest Project2.dpr.15: s := r; 00419F23 8D45F8 lea eax,[ebp-$08] 00419F26 8B55FC mov edx,[ebp-$04] 00419F29 E8FED1FEFF call @UStrLAsg Project2.dpr.16: Writeln(NativeInt(PChar(@s[1]))); 00419F2E 8D45F8 lea eax,[ebp-$08] 00419F31 E85AD3FEFF call @UniqueStringU 00419F36 8BD0 mov edx,eax 00419F38 A18CE64100 mov eax,[$0041e68c] 00419F3D E82AB2FEFF call @Write0Long 00419F42 E805B5FEFF call @WriteLn 00419F47 E81CA1FEFF call @_IOTest Project2.dpr.17: Result := r; 00419F4C 8BC3 mov eax,ebx 00419F4E 8B55FC mov edx,[ebp-$04] 00419F51 E88ED1FEFF call @UStrAsg Project2.dpr.18: Writeln(NativeInt(PChar(@Result[1]))); 00419F56 8BC3 mov eax,ebx 00419F58 E833D3FEFF call @UniqueStringU 00419F5D 8BD0 mov edx,eax 00419F5F A18CE64100 mov eax,[$0041e68c] 00419F64 E803B2FEFF call @Write0Long 00419F69 E8DEB4FEFF call @WriteLn 00419F6E E8F5A0FEFF call @_IOTest Project2.dpr.13:r:=“你好”; 00419EF8 8D45FC lea eax,[ebp-$04] 00419EFB BAA89F4100 mov edx,$00419fa8 00419F00 E827D2FEFF呼叫@USTRASG 项目2.dpr.14:书面(国家(PChar(@r[1])); 00419F05 8D45FC lea eax,[ebp-$04] 00419F08 E883D3FEFF呼叫@UniqueStringU 00419F0D 8BD0 mov edx,eax 00419F0F A18CE64100 mov eax,[$0041e68c] 00419F14 E853B2FEFF调用@Write0Long 00419F19 E82EB5FEFF调用@WriteLn 00419F1E E845A1FEFF呼叫测试 项目2.dpr.15:s:=r; 00419F23 8D45F8 lea eax,[ebp-$08] 00419F26 8B55FC mov edx,[ebp-$04] 00419F29 E8FED1FEFF呼叫@USTRASG Project2.dpr.16:Writeln(NativeInt(PChar(@s[1])); 00419F2E 8D45F8 lea eax,[ebp-$08] 00419F31 E85AD3FEFF呼叫@UniqueStringU 00419F36 8BD0 mov edx,eax 00419F38 A18CE64100 mov eax,[$0041e68c] 00419F3D E82AB2FEFF调用@Write0Long 00419F42 E805B5FEFF调用@WriteLn 00419F47 E81CA1FEFF呼叫测试 项目2.dpr.17:结果:=r; 00419F4C 8BC3 mov eax,ebx 00419F4E 8B55FC mov edx,[ebp-$04] 00419F51 E88ED1FEFF呼叫@UStrAsg Project2.dpr.18:Writeln(NativeInt(PChar(@Result[1])); 00419F56 8BC3 mov eax,ebx 00419F58 E833D3FEFF调用@UniqueStringU 00419F5D 8BD0 mov edx,eax 00419F5F A18CE64100 mov eax,[$0041e68c] 00419F64 E803B2FEFF调用@Write0Long 00419F69 E8DEB4FEFF调用@WriteLn 00419F6E E8F5A0FEFF呼叫测试
UniqueStringU
的调用正在执行写入时复制中的复制。

那么UniqueStringU会复制字符串的内容吗?内存中会有3份“Hello”,对吗?实际上会有4份。只读内存中的常量和三个副本;结果:=r;字符串是否只有一个副本?正确。或者如果您将
PChar(@r[1])
替换为
PChar(r)
,这实际上是更常见的强制转换,因为它保证为空terminated@David虽然你在力学上是正确的,但实际发生的事情要微妙一些。编译器不仅仅假设通过索引它可以创建一个唯一的字符串。在上面的例子中,它是以元素的地址作为原因的。