
              CHAPTER 12 - Pointers and Dynamic Allocation


             For  certain  types of programs, pointers  and  dynamic
        allocation can be a tremendous advantage, but many  programs
        do not need such a high degree of data structure.  For  that
        reason,  it would probably be to your advantage  to  lightly
        skim over these topics and come back to them later when  you
        have  a substantial base of Pascal  programming  experience.
        It would be good to at least skim over this material  rather
        than  completely neglecting it, so you will have an idea  of
        how  pointers and dynamic allocation work and that they  are
        available for your use when needed.

             A complete understanding of this material will  require
        deep  concentration  as  it  is  complex  and  not  at   all
        intuitive.   Nevertheless, if you pay close  attention,  you
        will have a good grasp of pointers and dynamic allocation in
        a short time.

                WHAT ARE POINTERS, AND WHAT GOOD ARE THEY?

             Examine the program named POINT for your first  example
        of  a  program using pointers.  In the var  declaration  you
        will  see  two variables named Where and Who that  have  the
        symbol ^ in front of their types.  This defines them, not as
        variables,  but as pointers to integer type  variables.   In
        line  12 of the program, the variable Index is assigned  the
        value of 17 for purposes of illustration.  The pointer named
        Where  is  then assigned the address of the  variable  Index
        which  means  that it does not contain the value of  17,  it
        contains  the  address  of the storage  location  where  the
        variable  Index  is stored.  In like manner, we  assign  the
        address  of  Index to the pointer named Who.  It  should  be
        obvious  to  you that Addr is a TURBO Pascal  function  that
        returns the address of its argument.

                        HOW DO WE USE THE POINTERS?

             It  should  be clear to you that we now have  a  single
        variable  named Index with two pointers pointing at it.   If
        the  pointers are useful, we should be able to do  something
        with  them  now, so we simply print out  the  same  variable
        three different ways in line 15.  When we write "Where^", we
        are  telling  the system that we are not interested  in  the
        pointer itself but instead we are interested in the data  to
        which   the  pointer  points.   This  is  referred   to   as
        dereferencing  the  pointer.  Careful study  of  the  output
        fields  in  line 15 will reveal that we  first  display  the
        value  of Index, then the value to which the  pointer  Where
        points,  and  finally  the value to which  the  pointer  Who
        points.  Since both pointers point to the variable Index, we
        are  essentially displaying the value of Index three  times.
        You will confirm this when you compile and run this program.


                                 Page 73









              CHAPTER 12 - Pointers and Dynamic Allocation



             In  line 17, we tell the system to assign the value  of
        23  to the variable to which the pointer Where points as  an
        illustration.   If  you  understood the  discussion  in  the
        previous paragraph, you will understand that we are actually
        assigning  the variable named Index the value of 23  because
        that is where the pointer named Where is pointing.  In  line
        18, we once again display the value of the variable Index  3
        times  just  as  we did in line 15.  It  would  be  to  your
        advantage  to compile and run this program to see  that  the
        value  of 17 is output three times, then the value of 23  is
        output three times.

             In  a program as simple as this, the value of  pointers
        is  not  at all clear but a simple program  is  required  in
        order  to  make the technique clear.   Display  the  program
        named  POINT  on your monitor again because we are  not  yet
        finished with it.

                            A FEW MORE POINTERS

             In  line 4, we define a new type named Int_Point  which
        is  a pointer to an integer type variable.  We use this  new
        type in line 9 to define three more pointers and in line 20,
        we  assign  one of them the address of  the  variable  named
        Index.   Since the pointers are of identical types, in  line
        21 we can assign Pt2 the value of Pt1, which is actually the
        address of the variable named Index.  Likewise, the  pointer
        Pt3  is  assigned the value of Pt2, and we  have  all  three
        pointers  pointing to the variable named Index.  If you  are
        using  TURBO Pascal version 4.0, you are allowed  to  assign
        pointers  like this only if they have the same  type,  which
        these three do.  However, since the pointers named Where and
        Who are assigned individually, they are not of the same type
        according to the rules of Pascal and if line 14 were changed
        to  read  "Who := Where;", a compilation error  would  occur
        with  TURBO Pascal version 4.0.  This error would not  occur
        with TURBO Pascal 3.0 since it is a little less stringent in
        its type checking.

             Finally,  we assign the only variable in  this  program
        which is named Index the value of 151 in line 23 and display
        the value 151 three times as we did above.  Compile and  run
        this  program again to see that it does indeed  display  the
        value 151 three times.

                 THIS IS JUST FOR TURBO PASCAL VERSION 4.0

             If  you are using TURBO Pascal version 4.0, you  should
        display  the  program named POINT4 on your  monitor  for  an
        example  of another new extension to the Pascal  programming


                                 Page 74









              CHAPTER 12 - Pointers and Dynamic Allocation


        language by Borland.  This program is identical to the  last
        except in lines 13, 14 and 20, where the symbol @ is used to
        denote  the  address of the variable index rather  than  the
        function  "Addr".   This is only available in  TURBO  Pascal
        version  4.0  as  a convenience to you.   In  ANSI  standard
        Pascal  the @ symbol is used as a synonym for the  ^  symbol
        but  Borland  chose  to use it for  a  completely  different
        purpose.  If you are using TURBO Pascal 3.0, you will not be
        able  to compile and run this program, but nothing  is  lost
        because it is identical to the previous one.

                    OUR FIRST LOOK AT DYNAMIC ALLOCATION

             If you examine the file named POINTERS, you will see  a
        very trivial example of pointers and how they are used  with
        dynamically  allocated variables.  In the  var  declaration,
        you  will  see that the two variables have a ^ in  front  of
        their  respective types once again, defining  two  pointers.
        They  will  be  used  to  point  to  dynamically   allocated
        variables that have not yet been defined.

             The  pointer  My_Name is a pointer to  a  20  character
        string.  The pointer actually points to an address somewhere
        within  the  computer memory, but we don't know  where  yet.
        Actually,  there  is nothing for it to point at  because  we
        have  not defined a variable.  After we assign it  something
        to  point  to,  we can use the pointer to  access  the  data
        stored at that address.

             Your  computer has some amount of memory  installed  in
        it. If it is an IBM-PC or compatible, it can have up to 640K
        of  RAM  which  is addressable  by  various  programs.   The
        operating system requires about 60K of the total, and if you
        are  using TURBO Pascal version 3.0, it requires about  35K,
        but  if you are using version 4.0, it requires  about  110K.
        The  TURBO Pascal program can use up to 64K.   Adding  those
        three  numbers together results in about 159K or 234K.   Any
        memory you have installed in excess of that is available for
        the  stack  and  the heap.  The stack  is  a  standard  area
        defined  and controlled by DOS that can grow and  shrink  as
        needed.   Many books are available to define the  stack  and
        its use if you are interested in more information on it.

                             WHAT IS THE HEAP?

             The  heap  is  a Pascal defined  entity  that  utilizes
        otherwise   unused   memory  to  store  data.    It   begins
        immediately  following  the program and grows  as  necessary
        upward toward the stack which is growing downward.  As  long
        as  they never meet, there is no problem.  If they  meet,  a
        run-time error is generated.  The heap is therefore  outside


                                 Page 75









              CHAPTER 12 - Pointers and Dynamic Allocation


        of the 64K limitation of TURBO Pascal and many other  Pascal
        compilers.

             TURBO Pascal version 4.0 does not limit us to 64K,  but
        there  are other reasons for using the heap in  addition  to
        the 64K limitation.  These should be evident as we learn how
        the heap works.

             If  you  did not understand the  last  few  paragraphs,
        don't  worry.   Simply remember that  dynamically  allocated
        variables are stored on the heap and do not count in the 64K
        limitation placed upon you by some compilers.

             Back  to  our  example  program,  POINTERS.   When   we
        actually  begin  executing the program, we  still  have  not
        defined the variables we wish to use to store data in.   The
        first  executable statement in line 10 generates a  variable
        for us with no name and stores it on the heap.  Since it has
        no name, we cannot do anything with it, except for the  fact
        that  we do have a pointer My_Name that is pointing  to  it.
        By  using the pointer, we can store up to 20  characters  in
        it, because that is its type, and later go back and retrieve
        it.

                        WHAT IS DYNAMIC ALLOCATION?

             The  variable we have just described is  a  dynamically
        allocated  variable  because  it was not defined  in  a  var
        declaration,   but  with  a  "New"  procedure.   The   "New"
        procedure  creates  a variable of the type  defined  by  the
        pointer,  puts  it  on the heap,  and  finally  assigns  the
        address  of  the  variable  to  the  pointer  itself.   Thus
        My_Name contains the address of the variable generated.  The
        variable  itself  is referenced by using the pointer  to  it
        followed by a ^, just like in the last program, and is read,
        "the variable to which the pointer points".

             The statement in line 11 assigns a place on the heap to
        an  integer  type variable and puts its address  in  My_Age.
        Following  the  "New"  statements  we  have  two  assignment
        statements  in  which  the  two  variables  pointed  at  are
        assigned values compatible with their respective types,  and
        they  are both written out to the video display in much  the
        same manner as we did in the program named POINT.

                 GETTING RID OF DYNAMICALLY ALLOCATED DATA

            The two statements in lines 19 and 20 are  illustrations
        of  the way the dynamically allocated variables are  removed
        from use.  When they are no longer needed, they are disposed



                                 Page 76









              CHAPTER 12 - Pointers and Dynamic Allocation


        of with the Dispose procedure which frees up their space  on
        the heap so it can be reused.

             In   such   a  simple  program,  pointers   cannot   be
        appreciated, but it is necessary for a simple  illustration.
        In  a large, very active program, it is possible  to  define
        many  variables, dispose of some of them, define  more,  and
        dispose of more, etc.  Each time some variables are disposed
        of,  their  space  is then  made  available  for  additional
        variables defined with the "New" procedure.

             The heap can be made up of any assortment of variables,
        they do not have to all be the same.  One point must be kept
        in  mind.   Anytime a variable is defined, it  will  have  a
        pointer  pointing to it.  The pointer is the only  means  by
        which  the variable can be accessed.  If the pointer to  the
        variable is lost or changed, the data itself is lost for all
        practical purposes.

             Compile and run this program and examine the output.

                       DYNAMICALLY STORING RECORDS;

             The next example program, DYNREC, is a repeat of one we
        studied  in an earlier chapter.  For your  own  edification,
        review the example program BIGREC before going ahead in this
        chapter.   Assuming  that you are back in DYNREC,  you  will
        notice  that this program looks very similar to the  earlier
        one,  and in fact they do exactly the same thing.  The  only
        difference  in  the type declaration is the  addition  of  a
        pointer  Person_Id,  and in the var declaration,  the  first
        four  variables  are  defined as  pointers  here,  and  were
        defined as record variables in the last program.

             A  point  should  be  made  here.   Pointers  are   not
        generally  used in very small programs.  This program  is  a
        good bit larger than the last and should be a clue to you as
        to why such a trivial program was used to introduce pointers
        in  this  tutorial.   A  very  small,  concise  program  can
        illustrate  a  topic  much  better  that  an  large  complex
        program, but we must go on to more useful constructs of  any
        new topic.

                  WE JUST BROKE THE GREAT RULE OF PASCAL

             Notice  in  the  type  declaration  that  we  used  the
        identifier  Person in line 18 before we defined it  in  line
        19,  which is illegal to do in Pascal.  Foreseeing the  need
        to  define a pointer prior to the record, the  designers  of
        Pascal  allow us to break the rule in this one  place.   The
        pointer  could  have been defined after the record  in  this


                                 Page 77









              CHAPTER 12 - Pointers and Dynamic Allocation


        particular  case,  but  it was more  convenient  to  put  it
        before, and in the next example program, it will be required
        to put it before the record.  We will get there soon.

             Since Friend is really 50 pointers, we have now defined
        53 different pointers to records, but so far have defined no
        variables other than Temp and Index.  We immediately use the
        New  procedure  to dynamically allocate a record  with  Self
        pointing  to it, and use the pointer so defined to fill  the
        dynamically  allocated record.  Compare this to the  program
        named   BIGREC and you will see that it is identical  except
        for  the addition of the "New" and adding the ^ to each  use
        of the pointer to designate the data pointed to.

                        THIS IS A TRICK, BE CAREFUL

             Now  go  down to line 48 where Mother  is  allocated  a
        record and is then pointing to the record.  It seems an easy
        thing to do then to simply assign all of the values of  self
        to all the values of mother as shown in the next  statement,
        but  it doesn't work.  All the statement does, is  make  the
        pointer  Mother  point  to  the same  place  where  Self  is
        pointing because we did a pointer assignment.  The data that
        was allocated to the pointer Mother is now somewhere on  the
        heap,  but we don't know where, and we cannot find  it,  use
        it, or deallocate it.  This is an example of losing data  on
        the  heap.   The  proper  way  is  given  in  the  next  two
        statements  where  all fields of Father are defined  by  all
        fields  of  Mother which is pointing at  the  original  Self
        record.   Note that since Mother and Self are both  pointing
        at  the same record, changing the data with  either  pointer
        results in the data appearing to be changed in both  because
        there is, in fact, only one field where the data is stored.

             In  order  to  Write from or Read  into  a  dynamically
        assigned  record it is necessary to use a  temporary  record
        since  dynamically  assigned records are not allowed  to  be
        used  in  I/O statements.  This is illustrated in  lines  57
        through 63 of the program where some data is written to  the
        monitor.

             Finally,   the  dynamically  allocated  variables   are
        disposed  of  prior  to ending the program.   For  a  simple
        program such as this, it is not necessary to dispose of them
        because all dynamic variables are disposed of  automatically
        when  the program is terminated and we return to DOS or  the
        TURBO  Pascal  integrated environment.  Notice that  if  the
        "Dispose(Mother);"  statement was included in  the  program,
        the data could not be found due to the lost pointer, and the
        program would be unpredictable, probably leading to a system
        crash.


                                 Page 78









              CHAPTER 12 - Pointers and Dynamic Allocation



                       SO WHAT GOOD IS THIS ANYWAY?

             Remember  when you were initially studying  BIGREC?   I
        suggested  that you see how big you could make the  constant
        Number_Of_Friends  before  you ran out of memory.   At  that
        time  we found that it could be made slightly  greater  than
        1000   before  we  got  the  memory  overflow   message   at
        compilation.  Try the same thing with DYNREC to see how many
        records  it  can handle, remembering that  the  records  are
        created dynamically, so you will have to run the program  to
        actually run out of memory.  The final result will depend on
        how  much  memory you have installed, and  how  many  memory
        resident programs you are using such as "Sidekick".  If  you
        have  a  full  memory of 640K, I  would  suggest  you  start
        somewhere above 8000 records of Friend.

             Now  you  should  have  a  good  idea  of  why  Dynamic
        Allocation can be used to greatly increase the usefulness of
        your programs.  There is, however, one more important  topic
        we  must  cover on dynamic allocation.  That is  the  linked
        list.

                          WHAT IS A LINKED LIST?

             Understanding  and  using a linked list is by  far  the
        most  baffling  topic  you will confront  in  Pascal.   Many
        people  simply throw up their hands and never try to  use  a
        linked list.  I will try to help you understand it by use of
        an  example  and lots of explanation.  Examine  the  program
        named LINKLIST for an example of a linked list.  I tried  to
        keep it short so you could see the entire operation and  yet
        do something meaningful.

             To begin with, notice that there are two types  defined
        in  lines  4 and 6, a pointer to the record and  the  record
        itself.  The record, however, has one thing about it that is
        new  to  us, the last entry, Next is a  pointer  to  another
        record  of this type.  This record then, has the ability  to
        point to itself, which would be trivial and meaningless,  or
        to another record of the same type which would be  extremely
        useful  in  some cases.  In fact, this is the way  a  linked
        list is used.  I must point out, that the pointer to another
        record,  in this case called Next, does not have to be  last
        in the list, it can be anywhere it is convenient for you.

             A  couple of pages ago, we discussed the fact  that  we
        had to break the great rule of Pascal and use an  identifier
        before it was defined.  This is the reason the exception  to
        the  rule  was  allowed.  Since the pointer  points  to  the
        record, and the record contains a reference to the  pointer,


                                 Page 79









              CHAPTER 12 - Pointers and Dynamic Allocation


        one  has  to be defined after being used, and  by  rules  of
        Pascal, the pointer can be defined first, provided that  the
        record  is  defined  immediately following it.   That  is  a
        mouthful  but  if  you  just use the  syntax  shown  in  the
        example, you will not get into trouble with it.

                            STILL NO VARIABLES?

             It  may  seem  strange,  but  we  still  will  have  no
        variables defined, except for our old friend Index.  In fact
        for  this example, we will only define 3 pointers.   In  the
        last example we defined 54 pointers, and had lots of storage
        room.  Before we are finished, we will have at least a dozen
        pointers but they will be stored in our records, so they too
        will be dynamically allocated.

             Lets  look at the program itself now.  In line  20,  we
        create  a dynamically allocated record and define it by  the
        pointer  Place_In_List.   It is composed of the  three  data
        fields,  and  another pointer.  We define  Start_Of_List  to
        point  to  the first record created, and we  will  leave  it
        unchanged throughout the program.  The pointer Start_Of_List
        will  always  point to the first record in the  linked  list
        which we are building up.

                   WHAT IS "nil" AND WHAT IS IT USED FOR?

             We  define the three variables in the record to be  any
        name  we  desire  for illustrative  purposes,  and  set  the
        pointer  in  the record to "nil".  The word nil  is  another
        reserved  word that doesn't give the pointer an address  but
        defines it as empty.  A pointer that is currently nil cannot
        be  used to manipulate data because it has no value, but  it
        can  be tested in a logical statement to see if it  is  nil.
        It  is therefore a dummy assignment.  With all of that,  the
        first record is completely defined.

                        DEFINING THE SECOND RECORD

             When  you  were young you may have played  a  searching
        game  in  which you were given a clue telling you  where  to
        find  the  next  clue.   The next clue had  a  clue  to  the
        location  of  the third clue.  You kept going from  clue  to
        clue  until  you found the prize.  You  simply  exercised  a
        linked  list.  We will now build up the same kind of a  list
        in  which each record will tell us where the next record  is
        at.

             In  lines  27  through 33 we  will  define  the  second
        record.   Our goal will be to store a pointer to the  second
        record  in the pointer field of the first record.  In  order


                                 Page 80









              CHAPTER 12 - Pointers and Dynamic Allocation


        to  keep track of the last record, the one in which we  need
        to  update  the  pointer, we will keep a pointer  to  it  in
        Temp_Place.   Now  we can dynamically allocate  another  New
        record  and  use  Place_In_List  to  point  to  it.    Since
        Temp_Place  is now pointing at the first record, we can  use
        it to store the value of the pointer which points to the new
        record which we do in line 29.  The 3 data fields of the new
        record are assigned nonsense data for our illustration,  and
        the pointer field of the new record is assigned nil.

             Lets  review our progress to this point.  We  now  have
        the  first record with a person's name and a pointer to  the
        second record, and a second record with a different person's
        name  and  a  pointer  assigned nil.   We  also  have  three
        pointers, one pointing to the first record, one pointing  to
        the  last record, and one we used just to get here since  it
        is  only  a temporary pointer.  If you  understand  what  is
        happening so far, lets go on to add some additional  records
        to  the  list.   If  you are confused,  go  back  over  this
        material again.

                             TEN MORE RECORDS

             The next section of code is contained within a for loop
        so  the  statements are simply repeated ten times.   If  you
        observe  carefully, you will notice that the statements  are
        identical  to the second group of statements in the  program
        (except  of course for the name assigned).  They operate  in
        exactly  the same manner, and we end up with ten more  names
        added  to  the  list.  You will now see  why  the  temporary
        pointer was necessary, but pointers are cheap, so feel  free
        to use them at will. A pointer only uses 4 bytes of memory.

                      FINALLY, A COMPLETE LINKED LIST

             We now have generated a linked list of twelve  entries.
        We  have a pointer pointing at the first entry, and  another
        pointer  pointing at the last.  The only data stored  within
        the program itself are three pointers, and one integer,  all
        of  the  data is on the heap.  This is one  advantage  to  a
        linked  list,  it uses very little local memory, but  it  is
        costly  in terms of programming.  (Keep in mind that all  of
        the data must be stored somewhere in memory, and in the case
        of  the linked list, it is stored on the heap.)  You  should
        never  use  a linked list simply to save  memory,  but  only
        because  a  certain program lends itself well to  it.   Some
        sorting  routines  are  extremely fast because  of  using  a
        linked  list,  and  it could be advantageous  to  use  in  a
        database.




                                 Page 81









              CHAPTER 12 - Pointers and Dynamic Allocation


             Following  is  a graphical representation of  what  the
        linked list looks like.

        Start_Of_List---->John
                          Q
                          Doe
                          Next---->Mary
                                   R
                                   Johnson
                                   Next---->William
                                            S
                                            Jones
                                            Next---->
                                                 .
                                                 .
                                                 .
                                             ---->William
                                                  S
                                                  Jones
                                                  Next---->nil

                      HOW DO WE GET TO THE DATA NOW?

             Since  the data is in a list, how can we get a copy  of
        the  fourth entry for example?  The only way is to start  at
        the beginning of the list and successively examine  pointers
        until  you  reach the desired one.  Suppose you are  at  the
        fourth and then wish to examine the third.  You cannot  back
        up,  because  you didn't define the list that way,  you  can
        only  start  at the beginning and count to the  third.   You
        could  have  defined  the  record  with  two  pointers,  one
        pointing forward, and one pointing backward.  This would  be
        a  doubly-linked  list and you could then go  directly  from
        entry four to entry three.

             Now  that  the list is defined, we will read  the  data
        from the list and display it on the video monitor.  We begin
        by defining the pointer, Place_In_List, as the start of  the
        list.   Now you see why it was important to keep a  copy  of
        where  the list started.  In the same manner as filling  the
        list,  we go from record to record until we find the  record
        with nil as a pointer.

             There are entire books on how to use linked lists,  and
        most Pascal programmers will seldom, if ever, use them.  For
        this  reason, additional detail is  considered  unnecessary,
        but  to be a fully informed Pascal programmer, some  insight
        is necessary.





                                 Page 82









              CHAPTER 12 - Pointers and Dynamic Allocation


                           PROGRAMMING EXERCISE

        1.  Write  a program to store a few names dynamically,  then
            display  the stored names on the monitor.  As your first
            exercise in dynamic allocation, keep it very simple.
















































                                 Page 83
