Delphi Copy-on-Write for String

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 delphi uses copy-on-write for strings. but the above function prints 3 different addresses for variables, r, s and results. So this is confusing. Is there only a copy of the string "Hello" in memory?

+5
source share
1 answer

Whenever you take the address of a string element, this is considered a record in the eyes of the compiler. As for this, you now have a raw pointer to the insides of the string, and who knows what you plan to do with it. Thus, from his point of view, he plays in safety. He decides to make a unique copy of the string so that you can do everything you do with your raw pointer.

The code you compile:

  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 UniqueStringU call is UniqueStringU by copy-on-write.

+9
source

Source: https://habr.com/ru/post/1232914/


All Articles