


                                                        Chapter 3
                                                         POINTERS

Because pointers are so important in C and C++, this chapter will 
review some of the more important topics concerning pointers.  
Even if you are extremely conversant in the use of pointers, you 
should not completely ignore this chapter because some new 
material unique to C++ is presented here.


POINTER REVIEW
-----------------------------------------------------------------
Examine the program named POINTERS.CPP for a   ==================
simple example of the use of pointers.  This      POINTERS.CPP
is a pointer review and if you are             ==================
comfortable with the use of pointers, you can 
skip this example program completely. A pointer in either ANSI-C 
or C++ is declared with an asterisk preceding the variable name.  
The pointer is then a pointer to a variable of that one specific 
type and should not be used with variables of other types.  Thus 
pt_int is a pointer to an integer type variable and should not be 
used with any other type.  Of course, an experienced C programmer 
knows that it is simple to coerce the pointer to be used with 
some other type by using a cast, but he must then assume the 
responsibility for its correct usage.

In line 12 the pointer named pt_int is assigned the address of 
the variable named pig and line 13 uses the pointer named pt_int 
to add the value of dog to the value of pig because the asterisk 
dereferences the pointer in exactly the same manner as standard 
C.  The address is used to print out the value of the variable 
pig in line 14 illustrating the use of a pointer with the stream 
output operator cout.  Likewise, the pointer to float named 
pt_float is assigned the address of x, then used in a trivial 
calculation in line 18.  Figure 3-1 is a graphical representation 
of the data space following execution of line 13.  Note that a 
box containing a dot represents a pointer.

If you are not completely comfortable with this trivial program 
using pointers, you should review the use of pointers in any good 
C programming book or Coronado Enterprises C tutorial before 
proceeding on because we will assume that you have a thorough 
knowledge of pointers throughout the remainder of this tutorial.  
It is not possible to write a C program of any significant size 
or complexity without the use of pointers.


CONSTANT POINTERS AND POINTERS TO CONSTANTS
-----------------------------------------------------------------
The definition of C++ allows a pointer to a constant to be 
defined such that the value to which the pointer points cannot be 
changed but the pointer itself can be moved to another variable 

                                                         Page 3-1

                                             Chapter 3 - Pointers

or constant.  The method of defining a pointer to a constant is 
illustrated in line 22.  In addition to a pointer to a constant, 
you can also declare a constant pointer, one that cannot be 
changed.  Line 23 illustrates this.  Note that neither of these 
pointers are used in illustrative code.

Either of these constructs can be used to provide additional 
compile time checking and improve the quality of your code.  If 
you know a pointer will never be moved due to its nature, you 
should define it as a constant pointer.  If you know that a value 
will not be changed, it can be defined as a constant and the 
compiler will tell you if you ever inadvertently attempt to 
change it.


A POINTER TO VOID
-----------------------------------------------------------------
The pointer to void is actually a part of the ANSI-C standard but 
is relatively new so it is commented upon here.  A pointer to 
void can be assigned the value of any other pointer type.  You 
will notice that the pointer to void named general is assigned an 
address of an int type in line 15 and the address of a float type 
in line 20 with no cast and no complaints from the compiler.  
This is a relatively new concept in C and C++.  It allows a 
programmer to define a pointer that can be used to point to many 
different kinds of things to transfer information around within a 
program.  A good example is the malloc() function which returns a 
pointer to void.  This pointer can be assigned to point to any 
entity, thus transferring the returned pointer to the correct 
type.

A pointer to void is aligned in memory in such a way that it can 
be used with any of the simple predefined types available in C++, 
or in ANSI-C for that matter.  They will also align with any 
compound types the user can define since compound types are 
composed of the simpler types.

Be sure to compile and execute this program.


DYNAMIC ALLOCATION AND DEALLOCATION
-----------------------------------------------------------------
Examine the program named NEWDEL.CPP for our   ==================
first example of the new and delete operators.     NEWDEL.CPP
The new and delete operators do dynamic        ==================
allocation and deallocation in much the same 
manner that malloc() and free() do in your old favorite C 
implementation.

During the design of C++, it was felt that since dynamic 
allocation and deallocation are such a heavily used part of the C 
programming language and would also be heavily used in C++, it 
should be a part of the language, rather than a library add-on.  

                                                         Page 3-2

                                             Chapter 3 - Pointers

The new and delete operators are actually a part of the C++ 
language and are operators, much like the addition operator or 
the assignment operator.  They are therefore very efficient, and 
are very easy to use as we will see in this example program.

Lines 14 and 15 illustrate the use of pointers in the tradition 
of C and line 16 illustrates the use of the new operator.  This 
operator requires one modifier which must be a type as 
illustrated here.  The pointer named point2 is now pointing at 
the dynamically allocated integer variable which exists on the 
heap, and can be used in the same way that any dynamically 
allocated variable is used in ANSI-C.  Line 18 illustrates 
displaying the value on the monitor which was assigned in line 
17.

Line 20 allocates another new variable and line 21 causes point2 
to refer to the same dynamically allocated variable as point1 is 
pointing to.  In this case, the reference to the variable that 
point2 was previously pointing to has been lost and it can never 
be used or deallocated.  It is lost on the heap until we return 
to the operating system when it will be reclaimed for further 
use, so this is obviously not good practice.  Note that point1 is 
deallocated with the delete operator in line 25, and point2 can 
not be deleted since it is now pointing to nothing.  Since the 
pointer point1 itself is not changed, it is actually still 
pointing to the original data on the heap.  This data could 
probably be referred to again using point1, but it would be 
terrible programming practice since you have no guarantee what 
the system will do with the pointer or the data.  The data 
storage is returned to the free list to be allocated in a 
subsequent call, and will soon be reused in any practical 
program.

Since the delete operator is defined to do nothing if it is 
passed a NULL value, it is legal to ask the system to delete the 
data pointed to by a pointer with the value of NULL, but nothing 
will actually happen.  It is actually wasted code.  The delete 
operator can only be used to delete data allocated by a new 
operator.  If the delete is used with any other kind of data, the 
operation is undefined and anything can happen.  According to the 
ANSI standard, even a system crash is a legal result of this 
illegal operation, and can be defined as such by the compiler 
writer.

In line 27, we declare some floating point variables.  You will 
remember that in C++ the variables do not have to be declared at 
the beginning of a block.  A declaration is an executable 
statement and can therefore appear anywhere in a list of 
executable statements.  One of the float variables is allocated 
within the declaration to illustrate that this can be done.  Some 
of the same operations are performed on these float type 
variables as were done on the int types earlier.


                                                         Page 3-3

                                             Chapter 3 - Pointers

Some examples of the use of a structure are given in lines 35 
through 41 and should be self explanatory.

Finally, since the new operator requires a type to determine the 
size of the dynamically allocated block, you may wonder how you 
can allocate a block of arbitrary size.  This is possible by 
using the construct illustrated in line 47 where a block of 37 
char sized entities, which will be 37 bytes, is allocated.  A 
block of 133 bytes greater than the size of the date structure is 
allocated in line 49.  It is therefore clear that the new 
operator can be used with all of the flexibility of the malloc() 
function which you are familiar with.  The brackets are required 
in lines 48 and 50 to tell the compiler that it is deallocating 
an array.

The standard functions which you have been using in C for dynamic 
memory management, malloc(), calloc(), and free(), are also 
available for use in C++ and can be used in the same manner they 
were used in C.  The new and delete operators should not be 
intermixed with the older function calls since the results may be 
unpredictable.  If you are updating code with the older function 
calls, continue to use them for any additions to the code.  If 
you are designing and coding a new program you should use the 
newer constructs because they are a built in part of the language 
rather than an add on and are therefore more efficient.

Be sure to compile and execute this program.


POINTERS TO FUNCTIONS
-----------------------------------------------------------------
Examine the program named FUNCPNT.CPP for an    =================
example of using a pointer to a function.  It      FUNCPNT.CPP
must be pointed out that there is nothing new   =================
here, the pointer to a function is available 
in ANSI-C as well as in C++ and works in the manner described 
here for both languages.  It is not regularly used by most C 
programmers, so it is briefly discussed here as a refresher.  If 
you are comfortable with the use of pointers to functions, you 
can skip this discussion entirely.

There is nothing unusual about this program except for the 
pointer to a function declared in line 7.  This declares a 
pointer to a function which returns nothing (void) and requires a 
single formal parameter, a float type variable.  You will notice 
that all three of the functions declared in lines 4 through 6 fit 
this profile and are therefore candidates to be called with this 
pointer.  If you have not used prototyping in C, these lines will 
look strange to you.  Don't worry about them at this point since 
we will study prototyping in the next chapter of this tutorial.

Observe that in line 14 we call the function print_stuff() with 
the parameter pi and in line 15 we assign the function pointer 

                                                         Page 3-4

                                             Chapter 3 - Pointers

named function_pointer the value of print_stuff() and use the 
function pointer to call the same function again in line 16.  
Lines 14 and 16 are therefore identical in what is accomplished 
because of the pointer assignment in line 15.  In lines 17 
through 22, a few more illustrations of the use of the function 
pointer are given.  You will be left to study these on your own.

Since we assigned the name of a function to a function pointer, 
and did not get an assignment error, the name of a function must 
be a pointer to that function.  This is exactly the case.  A 
function name is a pointer to that function, but it is a pointer 
constant and cannot be changed.  This is exactly the case we 
found when we studied arrays in ANSI-C at some point in our C 
programming background.  An array name is a pointer constant to 
the first element of the array.

Since the name of the function is a constant pointer to that 
function, we can assign the name of the function to a function 
pointer and use the function pointer to call the function.  The 
only caveat is that the return value and the number and types of 
parameters must be identical.  Most C and C++ compilers will not, 
and in fact, can not warn you of type mismatches between the 
parameter lists when the assignments are made.  This is because 
the assignments are done at runtime when no type information is 
available to the system, rather than at compile time when all 
type information is available.

The use and operation of pointers must be thoroughly understood 
when we get to the material on dynamic binding and polymorphism 
later in this tutorial.  It will be discussed in detail at that 
time.

Be sure to compile and execute this program.


PROGRAMMING EXERCISES
-----------------------------------------------------------------
1.  When dynamically allocated data is deleted, it is still 
    actually in memory, stored on the heap.  Repeat the output 
    statement from line 23 of NEWDEL.CPP immediately following 
    the delete in line 25 to see if the values are really still 
    there.  Repeat it once again just prior to the end of the 
    program when the data spaces should have been written over to 
    see if you get garbage out.  Even if your compiler reports 
    the correct data, it is terrible practice to count on this 
    data still being there because in a large dynamic program, 
    the heap space will be used repeatedly.

2.  Add a function to FUNCPNT.CPP which uses a single integer for 
    a parameter and attempt to call it by using the function 
    pointer to see if you get the correct data into the function.



                                                         Page 3-5
