Reputation: 35
I understand the concept of pointers and how to use, but I just want to clear up a bit of confusion in my head about assigning a pointer to a record sub-element already pointed to by another pointer...
I've seen some questions elsewhere that are I think asking the same thing, but the answers are in C...
If I have:
type
TDetails = record
Name : string;
Origin : string;
end;
TMsgData = record
ID : string;
Code : integer;
Details : TDetails;
end;
var
MessageData = array of TMsgData;
I can obviously get a pointer to specific record of TMsgData type by:
var
pMessageData = ^TMsgData;
begin
pMessageData := @MessageData[0];
...
And of course I can then access all the record elements using that pointer with standard dereferencing.
But, how do I get a new pointer to just the Details record of MessageData[0] using the first pointer? I want to avoid having a pointer to a pointer so if pMessageData is free'd I still have the other pointer.
If I do
name := pMessageData.Details.Name;
then Delphi will automatically dereference this to give me the value of name. So if I did:
var
pMessageDetails = ^TDetails;
begin
pMessageDetails = @pMessageData.Details;
*or*
pMessageDetails = Addr(pMessageData^.Details);
Do either of those give me a pointer to a pointer or a new pointer to the original record?
Upvotes: 1
Views: 627
Reputation: 109003
Let's be pedantic.
pMessageData
is a pointer to a TMsgData
. This means that pMessageData^
is a TMsgData
, and pMessageData^.Details
is its TDetails
.
A pointer to this record is therefore @(pMessageData^.Details)
, which can also be written Addr(pMessageData^.Details)
using the Addr
function.
Furthermore, @(pMessageData^.Details)
is parsed the same way as @pMessageData^.Details
, so you can omit the parentheses.
In fact, you can even omit the dereferencing operator and write simply @pMessageData.Details
.
Actually, you can easily verify that my conclusions are correct using Delphi itself:
procedure TForm1.FormCreate(Sender: TObject);
var
pMessageData: ^TMsgData;
p1, p2, p3, p4: ^TDetails;
begin
SetLength(MessageData, 3);
MessageData[1].ID := 'Alpha';
MessageData[1].Code := 123;
MessageData[1].Details.Name := 'Test';
MessageData[1].Details.Origin := 'NYC';
pMessageData := @MessageData[1];
p1 := @(pMessageData^.Details);
p2 := Addr(pMessageData^.Details);
p3 := @pMessageData^.Details;
p4 := @pMessageData.Details;
ShowMessage(p1^.Origin);
ShowMessage(p2^.Origin);
ShowMessage(p3^.Origin);
ShowMessage(p4^.Origin);
ShowMessage(NativeInt(p1).ToString);
ShowMessage(NativeInt(p2).ToString);
ShowMessage(NativeInt(p3).ToString);
ShowMessage(NativeInt(p4).ToString);
ShowMessage(NativeInt(@MessageData[1].Details).ToString); // same as last four
ExitProcess(0)
end;
Upvotes: 2