Recent

Author Topic: Understanding pointers  (Read 4075 times)

samsepiol

  • Newbie
  • Posts: 2
Understanding pointers
« on: February 10, 2017, 10:28:38 pm »
Hello guys, I have just recently started learning pascal (and programming generally) so forgive me my lack of knowledge  :)

I wrote the code below to help me understand the pointers but so far it's causing me a lot of confusion.
I can't seem to understand why in lines 21-24 only "test2" is written out, because if my understanding of pointers is right both "node1.NodePtr^.NodePtr" and "node2.NodePtr" should point to the same location, which is nil.

This is the same in lines 26,27 as line 26 writes out a random integer value and line 27 yields an error which I would expect from the previous line too.
Why don't those two lines of code behave the same?
Any help would be appreciated.

Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. type TypNodePtr = ^TypNode;
  4.      TypNode = record
  5.        Data:integer;
  6.        NodePtr:TypNodePtr;
  7.      end;
  8.  
  9. var node1,node2:TypNode;
  10.  
  11. begin
  12.   new(node1.NodePtr);
  13.   new(node2.NodePtr);
  14.  
  15.   node1.Data:=1;
  16.   node2.Data:=2;
  17.  
  18.   node1.NodePtr^:= node2;
  19.   node2.NodePtr:= nil;
  20.  
  21.   if node1.NodePtr^.NodePtr = nil then
  22.     writeln('test1');
  23.   if node2.NodePtr = nil then
  24.     writeln('test2');
  25.  
  26.   writeln(node1.NodePtr^.NodePtr^.Data);
  27.   writeln(node2.NodePtr^.Data);
  28.  
  29.   readln;
  30. end.


Thank you,
Sam

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Understanding pointers
« Reply #1 on: February 10, 2017, 11:43:56 pm »
I think you would understand pointers better if you declared your variables as pointers and worked with those pointer variables, rather than declaring and working with variables that are records.
Try this program:

Code: Pascal  [Select][+][-]
  1. program project2;
  2.  
  3. {$Mode objfpc}{$H+}
  4.  
  5. type
  6.   PNode = ^TNode;
  7.   TNode = record
  8.     data: integer;
  9.     nPtr: PNode;
  10.   end;
  11.  
  12. var
  13.   p1, p2: PNode;
  14.  
  15. begin
  16.   New(p2);
  17.   p2^.data:=2;
  18.   p2^.nPtr:=nil;
  19.  
  20.   New(p1);
  21.   p1^.data:=1;
  22.   p1^.nPtr:=p2;
  23.  
  24.   WriteLn('Assigned(p1) is ',Assigned(p1));
  25.   WriteLn('Assigned(p2) is ',Assigned(p2));
  26.   WriteLn('Assigned(p1^.nPtr) is ',Assigned(p1^.nPtr));
  27.   WriteLn('Assigned(p2^.nPtr) is ',Assigned(p2^.nPtr));
  28.   WriteLn('Assigned(p1^.nPtr^.nPtr) is ',Assigned(p1^.nPtr^.nPtr));
  29.  
  30.   WriteLn('p1^.data=',p1^.data);
  31.   WriteLn('p1^.nPtr^.data=',p1^.nPtr^.data);
  32.  
  33.   Dispose(p1);
  34.   Dispose(p2);
  35.  
  36.   ReadLn;
  37. end.
« Last Edit: February 10, 2017, 11:53:00 pm by howardpc »

eny

  • Hero Member
  • *****
  • Posts: 1634
Re: Understanding pointers
« Reply #2 on: February 10, 2017, 11:50:27 pm »
Without explaining all about pointers, line 18 should read:

  node1.NodePtr := @node2;

If you want test1 and test2 both printed.

You are creating a memory leak though.

And as howarpc already said, working purely with pointers makes indeed mores sense (i.e. not mixing static contents with dynamic contents).
« Last Edit: February 10, 2017, 11:53:18 pm by eny »
All posts based on: Win10 (Win64); Lazarus 2.0.10 'stable' (x64) unless specified otherwise...

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9913
  • Debugger - SynEdit - and more
    • wiki
Re: Understanding pointers
« Reply #3 on: February 11, 2017, 02:14:50 am »
There is a huge diff between
Code: Pascal  [Select][+][-]
  1.   node1.NodePtr^:= node2;
  2.   node1.NodePtr:= @node2;
  3.  

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)

samsepiol

  • Newbie
  • Posts: 2
Re: Understanding pointers
« Reply #4 on: February 11, 2017, 04:24:52 pm »
Thank you all, you helped me a lot. Working with pointers as variables instead of using records as variables works much better, also I didn't know about the @ thing so thanks for explaining, I have a much better understanding of pointers now :)

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1313
Re: Understanding pointers
« Reply #5 on: February 11, 2017, 09:28:03 pm »
The value of a pointer is the location of a variable. The value of a variable is some number that represents something.

The problem arises when the value of a pointer is the location of a pointer. Like, with objects.

Hint: if you think it's hard, don't try C. It features things like: (**(*NumberOfBricks)*)**, where each * means that it's a pointer.

 

TinyPortal © 2005-2018