Delphi strings and reference counting
Delphi uses reference counting with strings.
Do this mean that there is only one memory allocation for '1234567890' and all a,b,c,d, e and f.s reference to it?
type
TFoo = class
s: string;
end;
const
a = '1234567890';
b = a;
c : string = a;
开发者_Go百科
var
d: string;
e: string;
f: TFoo;
function GetStr1(const s: string): string;
begin
Result := s;
end;
function GetStr2(s: string): string;
begin
Result := s;
end;
begin
d := GetStr1(b);
e := GetStr2(c);
f := TFoo.Create;
f.s := a;
end;
Yes, there's only one allocation in your specific example. If you had used UniqueString
, as mghie says, or if you had built the string dynamically, then you end up with a new string allocation even if the string contents are the same as some other string.
However, an interesting fact about your specific example: there is actually no memory "allocated" for the string '1234567890' at all. The data for string constants is stored in the executable image on disk, and is paged in by the OS when the code accesses it. It takes up memory address space, as part of the entire executable module's in-memory mapping, but since it is backed by the original executable on disk, it doesn't form part of the process's committed memory and won't need backing in the page file.
For example, this program will report an access violation on run:
{$apptype console}
uses SysUtils;
const
s = '1234567890';
procedure Change(const r: string);
var
p: PChar;
begin
p := PChar(r);
p^ := 'x';
end;
begin
try
Change(s);
except
on e: Exception do
Writeln(e.Message);
end;
end.
Small addition to the answer by jxac:
A copy will also be created when UniqueString()
is called in code, when a character in the string is accessed by []
, and when the string is typecasted to PChar
. This happens even when the PChar
and the string element will only ever be read.
It's important to know how to force a unique string from a potentially shared one, because there are Windows API functions that must not be called with a read-only char pointer, which a PChar
to a string constant is. In that case the constant needs to be copied to a variable first, so casting it will return a PChar
pointing to writable memory.
yep, the strings are ref counted, a copy is created only when the contents are modified through a variable (copy on write semantics), more info here:
http://www.codexterity.com/delphistrings.htm
精彩评论