Can multiple string variables really refer to the same data?
-
26-10-2019 - |
Question
According to the information in the internet I found out that two following variables point to the same place in memory.
Could anyone propose a code example to demonstrate that in fact it is true (e.g. by changing one of the letter in the 1st variable and see that this change is visible from the second variable)?
procedure TForm1.Button1Click(Sender: TObject);
var
a, b: String;
begin
a := 'Test';
b := a;
showmessage (a);
showmessage (b);
end;
Solution
var
a, b: string;
begin
a := 'Test';
a := a + '!'; // added after Rob's comment below,
// makes sure a points to an allocation on the heap
b := a;
PChar(b)[3] := 'T';
ShowMessage(a); //--> TesT!
end;
OTHER TIPS
procedure TForm4.FormCreate(Sender: TObject);
var
a, b: string;
begin
a := 'Test';
b := a;
ShowMessage(BoolToStr(pointer(a) = pointer(b), true));
end;
The result is True
, so yes, a
and b
point to the same data.
Notice, however, that
procedure TForm4.FormCreate(Sender: TObject);
var
a, b: string;
begin
a := 'Test';
b := a;
b := 'Test2';
ShowMessage(BoolToStr(pointer(a) = pointer(b), true));
end;
displays False
, as it should be.
In addition, notice that
procedure TForm4.FormCreate(Sender: TObject);
var
a, b: string;
begin
a := 'Test';
b := a;
ShowMessage(BoolToStr(@a = @b, true));
end;
also displays False
, because a
and b
are different string (pointer) variables, so at some place in memory (@a
) is the address of the data of a
, and somewhere else (@b
) is the address of the data of b
. The first example shows that these two places in memory contain the same address, that is, that a
and b
contain the same data.
Normally Delphi use 'copy-on-write' semantics for strings, so you need a kind of hacking to do the trick, for example:
procedure TForm13.Button1Click(Sender: TObject);
const
Test: string = '12345';
var
S1, S2: string;
P: PChar;
begin
SetString(S1, PChar(Test), 5);
// we need to copy '12345' string from readonly memory to heap
S2:= S1;
// Now both S1 and S2 points to the same memory
P:= Pointer(S1);
P^:= 'A';
ShowMessage(S2); // 'A2345'
end;
Your question is not very clear for me. If you do :
begin
a := 'Test';
b := a;
a := a+'HH';
showmessage (a);
showmessage (b);
end;
I think you will see it...
OK may be more clear with this code
procedure TForm1.FormCreate(Sender: TObject);
var
a, b , s : string;
p : pointer;
begin
a := 'Test';
b := a;
// we see the 2 diff. var pointing on the same adress
s := Format('%p -> %p / %p -> %p', [@pointer(a),pointer(a),@pointer(b),pointer(b)] );
ShowMessage( 'first : '+s);
// we see the 2 diff. var pointing on different adresses
a := 'Test2';
s := Format('%p -> %p / %p -> %p', [@pointer(a),pointer(a),@pointer(b),pointer(b)] );
ShowMessage( 'second : '+s);
end;