文字列の要素のアドレスを取得すると、コンパイラの目にはと書かれています()。これまでのところ、文字列の内部への未加工のポインタを持ち、それを使って何をする予定かを知っています。したがって、その観点からは、安全です。それは文字列の一意のコピーを作ることを決定します。そのため、あなたは生のポインタを使ってやるような荒々しい行為を自由に行うことができます。
あなたが持っているコードは、これにコンパイルされます。
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
UniqueStringU
への呼び出しは、コピー・オン・ライトでコピーを実行しています。
UniqueStringUは文字列の内容をコピーしますか?メモリに「Hello」という3つのコピーがあります。 –
実際には4があります。読み取り専用メモリの定数1と3つのコピー。 –
私は例のコードで3つのwritelnステートメントを削除した場合、単にs:= r;結果:= r;文字列のコピーは1つしかありませんか? –