I have a code like this:
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;
People say that delphi uses copy-on-write for strings. but the above function prints 3 different Addresses for variable, r, s, and Result. So this is confusing.. Is there only a copy of 'Hello' string in memory?
Whenever you take the address of an element of a string, that counts as a write in the eyes of the compiler. As far as it is concerned, you now have a raw pointer to the internals of the string, and who knows what you plan to do with it. So, from its perspective, it plays safe. It decides to make a unique copy of the string, so that you are free to do whatever dastardly deed you plan to do with your raw pointer.
The code you have compiles to this:
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
The calls to UniqueStringU
are performing the copy in copy-on-write.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With