There is a huge diff between
node1.NodePtr^:= node2;
node1.NodePtr:= @node2;
In the first line, you assign to the space pointed to by node1.NodePtr.
This is the memory you allocated with "new(node1.NodePtr);"
So in the first line, a
copy of node2 is written to the memory at node1.NodePtr^
Later changes to node 2, to not affect that copy.
In the 2nd line, the address of node2 is written to node1.NodePtr.
This overwrites the address that is in node1.NodePtr, which is the address to the memory allocated by "new(node1.NodePtr);". So there is a leak.
If you do "node1.NodePtr:= @node2;" then you do not need the "new()" before, after all node2 already has memory of its own, and no copy is made.
Note in the case of the 2nd line, if node2 is a local var, then node2's memory is freed at the end of the procedure, and node1.NodePtr becomes invalid (it will not be nil, but it points to something unusable / potentially crashing on access)