2015-10-04 13 views
5

のために:デルファイコピー・オン・ライト私はこのようなコードを持っている文字列

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; 

人々は、デルファイは文字列をコピー・オン・ライトを使用していることを言います。上記の関数は変数、r、s、Resultに3つの異なるアドレスを出力します。だから、これは混乱しています..メモリに 'Hello'文字列のコピーだけがありますか?

答えて

9

文字列の要素のアドレスを取得すると、コンパイラの目にはと書かれています()。これまでのところ、文字列の内部への未加工のポインタを持ち、それを使って何をする予定かを知っています。したがって、その観点からは、安全です。それは文字列の一意のコピーを作ることを決定します。そのため、あなたは生のポインタを使ってやるような荒々しい行為を自由に行うことができます。

あなたが持っているコードは、これにコンパイルされます。

 
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への呼び出しは、コピー・オン・ライトでコピーを実行しています。

+0

UniqueStringUは文字列の内容をコピーしますか?メモリに「Hello」という3つのコピーがあります。 –

+0

実際には4があります。読み取り専用メモリの定数1と3つのコピー。 –

+0

私は例のコードで3つのwritelnステートメントを削除した場合、単にs:= r;結果:= r;文字列のコピーは1つしかありませんか? –

関連する問題