this is my sample code :
type
PData = ^TData;
TData = record
str : string;
strlist : TStringList;
end;
var
P1 : PData;
P2 : PData;
P3 : PData;
P4 : PData;
begin
New(P1);
New(P2);
P1.str := 'string';
// copy
P2^ := P1^;
P2.str := P2.str + '_copy';
Memo1.Lines.Add('This is P1:' + P1.str); //This is P1:string
Memo1.Lines.Add('This is P2:' + P2.str); //This is P2:string_copy
// so change P2'Data didn't change P1's Data
// but this :
New(P3);
New(P4);
P3.str := 'string';
P3.strlist := TStringList.Create;
P3.strlist.Add('one line');
// copy
P4^ := P3^;
// just add P4's data
P4.strlist.Add('two line');
Memo1.Lines.Add('P3''s Data:' + IntToStr(P3.strlist.Count));
Memo1.Lines.Add(P3.strlist.Text);
Memo1.Lines.Add('P4''s Data:' + IntToStr(P4.strlist.Count));
Memo1.Lines.Add(P4.strlist.Text);
{
P3's Data:2
one line
two line
P4's Data:2
one line
two line
}
end;
why when copy point data with a class
, it will change raw data , but when data is string
use P1^ := P2^
copy point data does not change raw data.
String is somewhat of a Delphi-managed special entity. In particular, Delphi uses a Copy-On-Write
strategy, i.e. when you do P2^ := P1^;
, P1.str
and P2.str
both point to the same string object. Delphi keeps track via an internal reference count how many references to the string object exist.
As soon as you do a write operation like P2.str := P2.str + '_copy'
, Delphi recognises that the string is in use more than once and creates an own copy for P2.str. This all happens in the background and normally you don't notice this.
On the other hand, P3.strlist and P4.strlist are ordinary pointers and always point to the same object. There is no automagical copying here whatsoever.
Strings are copied on demand. That means when you change the copied string, it will create a new instance of the changed string. For simplicity you can assume that a string copy is a copy of the string data.
When you assign a class instance only a pointer to that instance is copied, not the instance itself. After the copy there is still only one class instance. You can see that from your code as there is only one TStringList.Create in your code.
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