#

#

- Day 8
  - Pointers
    - What Is a Pointer?
      - Figure 8.1.
    - Listing 8.1. Demonstrating address of variables
      - Figure 8.2.
    - Storing the Address in a Pointer
      - Pointer Names
      - The Indirection Operator
      - Pointers, Addresses, and Variables
        - Figure 8.3.
      - Manipulating Data by Using Pointers
    - Listing 8.2. Manipulating data by using pointers
      - Examining the Address
    - Listing 8.3. Finding out what is stored in pointers
    - Pointers
    - Why Would You Use Pointers?
    - The Stack and the Free Store
      - new
      - delete
    - Listing 8.4. Allocating, using, and deleting pointers.
    - Memory Leaks
    - Creating Objects on the Free Store
    - Deleting Objects
    - Listing 8.5. Creating and deleting objects on the free store
    - Accessing Data Members
    - Listing 8.6. Accessing member data of objects
    - on the free store.
    - Member Data on the Free Store
    - Listing 8.7. Pointers as member data
    - The this Pointer
    - Listing 8.8. Using the this pointer
    - Stray or Dangling Pointers
    - Listing 8.9. Creating a stray pointer
    - const Pointers
      - const Pointers and const Member Functions
    - Listing 8.10. Using pointers to const objects
      - const this Pointers
    - Summary
    - Q&A
    - Workshop
      - Quiz
      - Exercises

## Day 8

## Pointers

One of the most powerful tools available to a C++ programmer is the ability to manipulate computer memory directly by using pointers. Today you will learn

- What pointers are.

- How to declare and use pointers.

- What the free store is and how to manipulate memory.

Pointers present two special challenges when learning C++: They can be somewhat confusing, and it isn't immediately obvious why they are needed. This chapter explains how pointers work, step by step. You will fully understand the need for pointers, however, only as the book progresses.

### What Is a Pointer?

  New Term: A pointer is a variable that holds a memory address.

To understand pointers, you must know a little about computer memory. Computer memory is divided into sequentially numbered memory locations. Each variable is located at a unique location in memory, known as its address. (This is discussed in the "Extra Credit" section following Day 5, "Functions.") Figure 8.1 shows a schematic representation of the storage of an `unsigned long` integer variable `theAge`.
Figure 8.1. A schematic representation of `theAge`.
Different computers number this memory using different, complex schemes. Usually programmers don't need to know the particular address of any given variable, because the compiler handles the details. If you want this information, though, you can use the `address of` operator (`&`), which is illustrated in Listing 8.1.

Listing 8.1. Demonstrating address of variables.

    1:   // Listing 8.1 Demonstrates address of operator
    2:   // and addresses of local variables
    3:
    4:   #include <iostream.h>
    5:
    6:   int main()
    7:   {
    8:      unsigned short shortVar=5;
    9:      unsigned long  longVar=65535;
    10:     long sVar = -65535;
    11:
    12:     cout << "shortVar:\t" << shortVar;
    13:     cout << " Address of shortVar:\t";
    14:     cout <<  &shortVar  _<< "\n";
    15:
    16:     cout << "longVar:\t"  << longVar;
    17:      cout  << " Address of longVar:\t" ;
    18:      cout <<  &longVar  _<< "\n";
    19:
    20:     cout << "sVar:\t"     << sVar;
    21:       cout     << " Address of sVar:\t" ;
    22:       cout     <<  &sVar     _<< "\n";
    23:
    24:  return 0;
    25: }

    Output: shortVar: 5       Address of shortVar: 0x8fc9:fff4
    longVar:  65535   Address of longVar:  0x8fc9:fff2
    sVar:    -65535   Address of sVar:     0x8fc9:ffee

(Your printout may look different.)

Analysis: Three variables are declared and initialized: a `short` in line 8, an `unsigned long` in line 9, and a `long` in line 10. Their values and addresses are printed in lines 12-16, by using the `address of` operator (`&`).
The value of `shortVar` is `5`, as expected, and its address is `0x8fc9:fff4` when run on my 80386-based computer. This complicated address is computer-specific and may change slightly each time the program is run. Your results will be different. What doesn't change, however, is that the difference in the first two addresses is two bytes if your computer uses two-byte `short` integers. The difference between the second and third is four bytes if your computer uses four-byte `long` integers. Figure 8.2 illustrates how the variables in this program would be stored in memory.
Figure 8.2. Illustration of variable storage.
There is no reason why you need to know the actual numeric value of the address of each variable. What you care about is that each one has an address and that the right amount of memory is set aside. You tell the compiler how much memory to allow for your variables by declaring the variable type; the compiler automatically assigns an address for it. For example, a `long` integer is typically four bytes, meaning that the variable has an address to four bytes of memory.

#### Storing the Address in a Pointer

Every variable has an address. Even without knowing the specific address of a given variable, you can store that address in a pointer.

For example, suppose that `howOld` is an integer. To declare a pointer called `pAge` to hold its address, you would write

    int *pAge = 0;

This declares `pAge` to be a pointer to `int`. That is, `pAge` is declared to hold the address of an `int`.

Note that `pAge` is a variable like any of the variables. When you declare an integer variable (type `int`), it is set up to hold an integer. When you declare a pointer variable like `pAge`, it is set up to hold an address. `pAge` is just a different type of variable.

In this example, `pAge` is initialized to zero. A pointer whose value is zero is called a null pointer. All pointers, when they are created, should be initialized to something. If you don't know what you want to assign to the pointer, assign `0`. A pointer that is not initialized is called a wild pointer. Wild pointers are very dangerous.

> NOTE: Practice safe computing: Initialize your pointers!

If you do initialize the pointer to `0`, you must specifically assign the address of `howOld` to `pAge`. Here's an example that shows how to do that:

    unsigned short int howOld = 50;     // make a variable
    unsigned short int * pAge = 0;      // make a pointer
    pAge = &howOld;                     // put howOld's address in pAge

The first line creates a variable--`howOld`, whose type is `unsigned short int`--and initializes it with the value `50`. The second line declares `pAge` to be a pointer to type `unsigned short int` and initializes it to zero. You know that `pAge` is a pointer because of the asterisk (`*`) after the variable type and before the variable name.

The third and final line assigns the address of `howOld` to the pointer `pAge`. You can tell that the address of `howOld` is being assigned because of the `address of` operator (`&`). If the `address of` operator had not been used, the value of `howOld` would have been assigned. That might, or might not, have been a valid address.

At this point, `pAge` has as its value the address of `howOld`. `howOld`, in turn, has the value `50`. You could have accomplished this with one less step, as in

    unsigned short int howOld = 50;       // make a variable
    unsigned short int * pAge = &howOld;  // make pointer to howOld

`pAge` is a pointer that now contains the address of the `howOld` variable. Using `pAge`, you can actually determine the value of `howOld`, which in this case is `50`. Accessing `howOld` by using the pointer `pAge` is called indirection because you are indirectly accessing `howOld` by means of`pAge`. Later today you will see how to use indirection to access a variable's value.

  New Term: Indirection means accessing the value at the address held by a pointer. The pointer provides an indirect way to get the value held at that address.

#### Pointer Names

Pointers can have any name that is legal for other variables. This book follows the convention of naming all pointers with an initial `p`, as in `pAge` or `pNumber`.

#### The Indirection Operator

The indirection operator (`*`) is also called the dereference operator. When a pointer is dereferenced, the value at the address stored by the pointer is retrieved.

Normal variables provide direct access to their own values. If you create a new variable of type `unsigned short int` called `yourAge`, and you want to assign the value in `howOld` to that new variable, you would write

    unsigned short int yourAge;
    yourAge = howOld;

A pointer provides indirect access to the value of the variable whose address it stores. To assign the value in `howOld` to the new variable `yourAge` by way of the pointer `pAge`, you would write

    unsigned short int yourAge;
    yourAge = *pAge;

The indirection operator (`*`) in front of the variable `pAge` means "the value stored at." This assignment says, "Take the value stored at the address in `pAge` and assign it to `yourAge`."

> NOTE: The indirection operator (`*`) is used in two distinct ways with pointers: declaration and dereference. When a pointer is declared, the star indicates that it is a pointer, not a normal variable. For example,

>     unsigned short * pAge = 0; // make a pointer to an unsigned short

> When the pointer is dereferenced, the indirection operator indicates that the value at the memory location stored in the pointer is to be accessed, rather than the address itself.

>     *pAge = 5; // assign 5 to the value at pAge

> Also note that this same character (`*`) is used as the multiplication operator. The compiler knows which operator to call, based on context.

#### Pointers, Addresses, and Variables

It is important to distinguish between a pointer, the address that the pointer holds, and the value at the address held by the pointer. This is the source of much of the confusion about pointers.

Consider the following code fragment:

    int theVariable = 5;
    int * pPointer = &theVariable ;

`theVariable` is declared to be an integer variable initialized with the value `5`. `pPointer` is declared to be a pointer to an integer; it is initialized with the address of `theVariable`.`pPointer` is the pointer. The address that `pPointer` holds is the address of `theVariable`. The value at the address that `pPointer` holds is `5`. Figure 8.3 shows a schematic representation of `theVariable` and `pPointer`.
Figure 8.3. A schematic representation of memory.

#### Manipulating Data by Using Pointers

Once a pointer is assigned the address of a variable, you can use that pointer to access the data in that variable. Listing 8.2 demonstrates how the address of a local variable is assigned to a pointer and how the pointer manipulates the values in that variable.

Listing 8.2. Manipulating data by using pointers.

    1:     // Listing 8.2 Using pointers
    2:
    3:     #include <iostream.h>
    4:
    5:     typedef unsigned short int USHORT;
    6:     int main()
    7:     {
    8:        USHORT myAge;         // a variable
    9:        USHORT * pAge = 0;    // a pointer
    10:       myAge = 5;
    11:       cout << "myAge: " << myAge << "\n";
    12:
    13:       pAge = &myAge;     // assign address of myAge to pAge
    14:
    15:       cout << "*pAge: " << *pAge << "\n\n";
    16:
    17:       cout << "*pAge = 7\n";
    18:
    19:       *pAge = 7;         // sets myAge to 7
    20:
    21:       cout << "*pAge: " << *pAge << "\n";
    22:       cout << "myAge: " << myAge << "\n\n";
    23:
    24:
    25:       cout << "myAge = 9\n";
    26:
    27:       myAge = 9;
    28:
    29:       cout << "myAge: " << myAge << "\n";
    30:       cout << "*pAge: " << *pAge << "\n";
    31:
    32:    return 0;
    33: }

    Output: myAge: 5
    *pAge: 5

    *pAge = 7
    *pAge: 7
    myAge: 7

    myAge = 9
    myAge: 9
    *pAge: 9

Analysis: This program declares two variables: an `unsigned short`, `myAge`, and a pointer to an `unsigned short, pAge`. `myAge` is assigned the value `5` on line 10; this is verified by the printout in line 11.
On line 13, `pAge` is assigned the address of `myAge`. On line 15, `pAge` is dereferenced and printed, showing that the value at the address that `pAge` stores is the `5` stored in `myAge`. In line 17, the value `7` is assigned to the variable at the address stored in `pAge`. This sets `myAge` to `7`, and the printouts in lines 21-22 confirm this.

In line 27, the value `9` is assigned to the variable `myAge`. This value is obtained directly in line 29 and indirectly (by dereferencing `pAge`) in line 30.

#### Examining the Address

Pointers enable you to manipulate addresses without ever knowing their real value. After today, you'll take it on faith that when you assign the address of a variable to a pointer, it really has the address of that variable as its value. But just this once, why not check to make sure? Listing 8.3 illustrates this idea.

Listing 8.3. Finding out what is stored in pointers.

    1:      // Listing 8.3 What is stored in a pointer.
    2:
    3:     #include <iostream.h>
    4:
    5:     typedef unsigned short int USHORT;
    6:     int main()
    7:     {
    8:        unsigned short int myAge = 5, yourAge = 10;
    9:        unsigned short int * pAge = &myAge;  // a pointer
    10:
    11:       cout << "myAge:\t" << myAge <<  "\tyourAge:\t" << yourAge << "\n";
    12:       cout << "&myAge:\t" << &myAge <<  "\t&yourAge:\t" << &yourAge <<"\n";
    13:
    14:       cout << "pAge:\t" << pAge << "\n";
    15:       cout << "*pAge:\t" << *pAge << "\n";
    16:
    17:       pAge = &yourAge;       // reassign the pointer
    18:
    19:       cout << "myAge:\t" << myAge <<  "\tyourAge:\t" << yourAge << "\n";
    20:       cout << "&myAge:\t" << &myAge <<  "\t&yourAge:\t" << &yourAge <<"\n";
    21:
    22:       cout << "pAge:\t" << pAge << "\n";
    23:       cout << "*pAge:\t" << *pAge << "\n";
    24:
    25:       cout << "&pAge:\t" << &pAge << "\n";
    26:    return 0;
    27: }
    Output: myAge:     5             yourAge:  10
    &myAge:    0x355C        &yourAge: 0x355E
    pAge:      0x355C
    *pAge:     5
    myAge:     5             yourAge:  10
    &myAge:    0x355C        &yourAge: 0x355E
    pAge:      0x355E
    *pAge:     10
    &pAge:     0x355A

(Your output may look different.)

Analysis: In line 8, `myAge` and `yourAge` are declared to be variables of type `unsigned short` integer. In line 9, `pAge` is declared to be a pointer to an `unsigned short` integer, and it is initialized with the address of the variable `myAge`.
Lines 11 and 12 print the values and the addresses of `myAge` and `yourAge`. Line 14 prints the contents of `pAge`, which is the address of `myAge`. Line 15 prints the result of dereferencing `pAge`, which prints the value at `pAge`--the value in `myAge`, or `5`.

This is the essence of pointers. Line 14 shows that `pAge` stores the address of `myAge`, and line 15 shows how to get the value stored in `myAge` by dereferencing the pointer `pAge`. Make sure that you understand this fully before you go on. Study the code and look at the output.

In line 17, `pAge` is reassigned to point to the address of `yourAge`. The values and addresses are printed again. The output shows that `pAge` now has the address of the variable `yourAge` and that dereferencing obtains the value in `yourAge`.

Line 25 prints the address of `pAge` itself. Like any variable, it has an address, and that address can be stored in a pointer. (Assigning the address of a pointer to another pointer will be discussed shortly.)

> DO use the indirection operator (`*`) to access the data stored at the address in a pointer. DO initialize all pointers either to a valid address or to `null` (`0`). DO remember the difference between the address in a pointer and the value at that address.

### Pointers

To declare a pointer, write the type of the variable or object whose address will be stored in the pointer, followed by the pointer operator (`*`) and the name of the pointer. For example,

    unsigned short int * pPointer = 0;

To assign or initialize a pointer, prepend the name of the variable whose address is being assigned with the `address of` operator (`&`). For example,

    unsigned short int theVariable = 5;

    unsigned short int * pPointer = & theVariable;

To dereference a pointer, prepend the pointer name with the dereference operator (`*`). For example,

    unsigned short int theValue = *pPointer

### Why Would You Use Pointers?

So far you've seen step-by-step details of assigning a variable's address to a pointer. In practice, though, you would never do this. After all, why bother with a pointer when you already have a variable with access to that value? The only reason for this kind of pointer manipulation of an automatic variable is to demonstrate how pointers work. Now that you are comfortable with the syntax of pointers, you can put them to good use. Pointers are used, most often, for three tasks:

- Managing data on the free store.

- Accessing class member data and functions.

- Passing variables by reference to functions.

This rest of this chapter focuses on managing data on the free store and accessing class member data and functions. Tomorrow you will learn about passing variables by reference.

### The Stack and the Free Store

In the "Extra Credit" section following the discussion of functions in Day 5, five areas of memory are mentioned:

- Global name space

- The free store

- Registers

- Code space

- The stack

Local variables are on the stack, along with function parameters. Code is in code space, of course, and global variables are in global name space. The registers are used for internal housekeeping functions, such as keeping track of the top of the stack and the instruction pointer. Just about all remaining memory is given over to the free store, which is sometimes referred to as the heap.

The problem with local variables is that they don't persist: When the function returns, the local variables are thrown away. Global variables solve that problem at the cost of unrestricted access throughout the program, which leads to the creation of code that is difficult to understand and maintain. Putting data in the free store solves both of these problems.

You can think of the free store as a massive section of memory in which thousands of sequentially numbered cubbyholes lie waiting for your data. You can't label these cubbyholes, though, as you can with the stack. You must ask for the address of the cubbyhole that you reserve and then stash that address away in a pointer.

One way to think about this is with an analogy: A friend gives you the 800 number for Acme Mail Order. You go home and program your telephone with that number, and then you throw away the piece of paper with the number on it. If you push the button, a telephone rings somewhere, and Acme Mail Order answers. You don't remember the number, and you don't know where the other telephone is located, but the button gives you access to Acme Mail Order. Acme Mail Order is your data on the free store. You don't know where it is, but you know how to get to it. You access it by using its address--in this case, the telephone number. You don't have to know that number; you just have to put it into a pointer (the button). The pointer gives you access to your data without bothering you with the details.

The stack is cleaned automatically when a function returns. All the local variables go out of scope, and they are removed from the stack. The free store is not cleaned until your program ends, and it is your responsibility to free any memory that you've reserved when you are done with it.

The advantage to the free store is that the memory you reserve remains available until you explicitly free it. If you reserve memory on the free store while in a function, the memory is still available when the function returns.

The advantage of accessing memory in this way, rather than using global variables, is that only functions with access to the pointer have access to the data. This provides a tightly controlled interface to that data, and it eliminates the problem of one function changing that data in unexpected and unanticipated ways.

For this to work, you must be able to create a pointer to an area on the free store and to pass that pointer among functions. The following sections describe how to do this.

#### new

You allocate memory on the free store in C++ by using the `new` keyword. `new` is followed by the type of the object that you want to allocate so that the compiler knows how much memory is required. Therefore, `new unsigned short int` allocates two bytes in the free store, and `new long` allocates four.

The return value from `new` is a memory address. It must be assigned to a pointer. To create an `unsigned` `short` on the free store, you might write

    unsigned short int * pPointer;
    pPointer = new unsigned short int;

You can, of course, initialize the pointer at its creation with

    unsigned short int * pPointer = new unsigned short int;

In either case, `pPointer` now points to an `unsigned short int` on the free store. You can use this like any other pointer to a variable and assign a value into that area of memory by writing

    *pPointer = 72;

This means, "Put 72 at the value in `pPointer`," or "Assign the value `72` to the area on the free store to which `pPointer` points."

If `new` cannot create memory on the free store (memory is, after all, a limited resource) it returns the null pointer. You must check your pointer for null each time you request new memory.

> WARNING: Each time you allocate memory using the `new` keyword, you must check to make sure the pointer is not null.

#### delete

When you are finished with your area of memory, you must call `delete` on the pointer. `delete` returns the memory to the free store. Remember that the pointer itself--as opposed to the memory to which it points--is a local variable. When the function in which it is declared returns, that pointer goes out of scope and is lost. The memory allocated with `new` is not freed automatically, however. That memory becomes unavailable--a situation called a memory leak. It's called a memory leak because that memory can't be recovered until the program ends. It is as though the memory has leaked out of your computer.

To restore the memory to the free store, you use the keyword `delete`. For example,

    delete pPointer;

When you delete the pointer, what you are really doing is freeing up the memory whose address is stored in the pointer. You are saying, "Return to the free store the memory that this pointer points to." The pointer is still a pointer, and it can be reassigned. Listing 8.4 demonstrates allocating a variable on the heap, using that variable, and deleting it.

> WARNING: When you call `delete` on a pointer, the memory it points to is freed. Calling `delete` on that pointer again will crash your program! When you delete a pointer, set it to zero (null). Calling `delete` on a null pointer is guaranteed to be safe. For example:

>     Animal *pDog = new Animal; delete pDog; //frees the memory

> >     pDog = 0; //sets pointer to null    //... delete pDog; //harmless

Listing 8.4. Allocating, using, and deleting pointers.

    1:     // Listing 8.4
    2:     // Allocating and deleting a pointer
    3:
    4:     #include <iostream.h>
    5:     int main()
    6:     {
    7:        int localVariable = 5;
    8:        int * pLocal= &localVariable;
    9:        int * pHeap = new int;
    10:       if (pHeap == NULL)
    11:        {
    12:            cout << "Error! No memory for pHeap!!";
    13:            return 0;
    14:        }
    15:       *pHeap = 7;
    16:       cout << "localVariable: " << localVariable << "\n";
    17:       cout << "*pLocal: " << *pLocal << "\n";
    18:       cout << "*pHeap: " << *pHeap << "\n";
    19:       delete pHeap;
    20:       pHeap = new int;
    21:       if (pHeap == NULL)
    22:       {
    23:            cout << "Error! No memory for pHeap!!";
    24:            return 0;
    25:       }
    26:       *pHeap = 9;
    27:       cout << "*pHeap: " << *pHeap << "\n";
    28:       delete pHeap;
    29:       return 0;
    30: }

    Output: localVariable: 5
    *pLocal: 5
    *pHeap: 7
    *pHeap: 9

Analysis: Line 7 declares and initializes a local variable. Line 8 declares and initializes a pointer with the address of the local variable. Line 9 declares another pointer but initializes it with the result obtained from calling `new int`. This allocates space on the free store for an `int`. Line 10 verifies that memory was allocated and the pointer is valid (not null). If no memory can be allocated, the pointer is null and an error message is printed.
To keep things simple, this error checking often won't be reproduced in future programs, but you must include some sort of error checking in your own programs.

Line 15 assigns the value `7` to the newly allocated memory. Line 16 prints the value of the local variable, and line 17 prints the value pointed to by `pLocal`. As expected, these are the same. Line 19 prints the value pointed to by `pHeap`. It shows that the value assigned in line 15 is, in fact, accessible.

In line 19, the memory allocated in line 9 is returned to the free store by a call to `delete`. This frees the memory and disassociates the pointer from that memory. `pHeap` is now free to point to other memory. It is reassigned in lines 20 and 26, and line 27 prints the result. Line 28 restores that memory to the free store.

Although line 28 is redundant (the end of the program would have returned that memory) it is a good idea to free this memory explicitly. If the program changes or is extended, it will be beneficial that this step was already taken care of.

### Memory Leaks

Another way you might inadvertently create a memory leak is by reassigning your pointer before deleting the memory to which it points. Consider this code fragment:

    1:   unsigned short int * pPointer = new unsigned short int;
    2:   *pPointer = 72;
    3:   pPointer = new unsigned short int;
    4:   *pPointer = 84;

Line 1 creates `pPointer` and assigns it the address of an area on the free store. Line 2 stores the value `72` in that area of memory. Line 3 reassigns `pPointer` to another area of memory. Line 4 places the value `84` in that area. The original area--in which the value `72` is now held--is unavailable because the pointer to that area of memory has been reassigned. There is no way to access that original area of memory, nor is there any way to free it before the program ends.

The code should have been written like this:

    1: unsigned short int * pPointer = new unsigned short int;
    2: *pPointer = 72;
    3: delete pPointer;
    4: pPointer = new unsigned short int;
    5: *pPointer = 84;

Now the memory originally pointed to by `pPointer` is deleted, and thus freed, in line 3.

> NOTE: For every time in your program that you call `new`, there should be a call to `delete`. It is important to keep track of which pointer owns an area of memory and to ensure that the memory is returned to the free store when you are done with it.

### Creating Objects on the Free Store

Just as you can create a pointer to an integer, you can create a pointer to any object. If you have declared an object of type `Cat`, you can declare a pointer to that class and instantiate a `Cat` object on the free store, just as you can make one on the stack. The syntax is the same as for integers:

    Cat *pCat = new Cat;

This calls the default constructor--the constructor that takes no parameters. The constructor is called whenever an object is created (on the stack or on the free store).

### Deleting Objects

When you call `delete` on a pointer to an object on the free store, that object's destructor is called before the memory is released. This gives your class a chance to clean up, just as it does for objects destroyed on the stack. Listing 8.5 illustrates creating and deleting objects on the free store.

Listing 8.5. Creating and deleting objects on the free store.

    1:    // Listing 8.5
    2:    // Creating objects on the free store
    3:
    4:     #include <iostream.h>
    5:
    6:     class SimpleCat
    7:     {
    8:     public:
    9:            SimpleCat();
    10:             ~SimpleCat();
    11     private:
    12             int itsAge;
    13        };
    14
    15        SimpleCat::SimpleCat()
    16        {
    17               cout << "Constructor called.\n";
    18               itsAge = 1;
    19        }
    20
    21        SimpleCat::~SimpleCat()
    22        {
    23               cout << "Destructor called.\n";
    24        }
    25
    26        int main()
    27        {
    28               cout << "SimpleCat Frisky...\n";
    29               SimpleCat Frisky;
    30               cout << "SimpleCat *pRags = new SimpleCat...\n";
    31               SimpleCat * pRags = new SimpleCat;
    32               cout << "delete pRags...\n";
    33               delete pRags;
    34               cout << "Exiting, watch Frisky go...\n";
    35        return 0;
    36 }

    Output: SimpleCat Frisky...
    Constructor called.
    SimpleCat *pRags = new SimpleCat..
    Constructor called.
    delete pRags...
    Destructor called.
    Exiting, watch Frisky go...
    Destructor called.

Analysis: Lines 6-13 declare the stripped-down class `SimpleCat`. Line 9 declares `SimpleCat`'s constructor, and lines 15-19 contain its definition. Line 10 declares `SimpleCat`'s destructor, and lines 21-24 contain its definition.
In line 29, `Frisky` is created on the stack, which causes the constructor to be called. In line 31, the `SimpleCat` pointed to by `pRags` is created on the heap; the constructor is called again. In line 33, delete is called on `pRags`, and the destructor is called. When the function ends, `Frisky` goes out of scope, and the destructor is called.

### Accessing Data Members

You accessed data members and functions by using the dot (`.`) operator for `Cat` objects created locally. To access the `Cat` object on the free store, you must dereference the pointer and call the dot operator on the object pointed to by the pointer. Therefore, to access the `GetAge` member function, you would write

     (*pRags).GetAge();

Parentheses are used to assure that `pRags` is dereferenced before `GetAge()` is accessed.

Because this is cumbersome, C++ provides a shorthand operator for indirect access: the `points-to` operator (`->`), which is created by typing the dash (`-`) immediately followed by the greater-than symbol (`>`). C++ treats this as a single symbol. Listing 8.6 demonstrates accessing member variables and functions of objects created on the free store.

Listing 8.6. Accessing member data of objects on the free store.

    1:     // Listing 8.6
    2:     // Accessing data members of objects on the heap
    3:
    4:      #include <iostream.h>
    5:
    6:      class SimpleCat
    7:      {
    8:      public:
    9:             SimpleCat() {itsAge = 2; }
    10:             ~SimpleCat() {}
    11:             int GetAge() const { return itsAge; }
    12:             void SetAge(int age) { itsAge = age; }
    13:     private:
    14:             int itsAge;
    15:        };
    16:
    17:        int main()
    18:        {
    19:               SimpleCat * Frisky = new SimpleCat;
    20:               cout << "Frisky is " << Frisky->GetAge() << " years old\n";
    21:               Frisky->SetAge(5);
    22:               cout << "Frisky is " << Frisky->GetAge() << " years old\n";
    23:               delete Frisky;
    24:        return 0;
    25: }

    Output: Frisky is 2 years old
    Frisky is 5 years old

Analysis: In line 19, a `SimpleCat` object is instantiated on the free store. The default constructor sets its age to `2`, and the `GetAge()` method is called in line 20. Because this is a pointer, the indirection operator (`->`) is used to access the member data and functions. In line 21, the `SetAge()` method is called, and `GetAge()` is accessed again in line 22.

### Member Data on the Free Store

One or more of the data members of a class can be a pointer to an object on the free store. The memory can be allocated in the class constructor or in one of its methods, and it can be deleted in its destructor, as Listing 8.7 illustrates.

Listing 8.7. Pointers as member data.

    1:  // Listing 8.7
    2:  // Pointers as data members
    3:
    4:    #include <iostream.h>
    5:
    6:    class SimpleCat
    7:    {
    8:    public:
    9:            SimpleCat();
    10:            ~SimpleCat();
    11:            int GetAge() const { return *itsAge; }
    12:            void SetAge(int age) { *itsAge = age; }
    13:
    14:            int GetWeight() const { return *itsWeight; }
    15:            void setWeight (int weight) { *itsWeight = weight; }
    16:
    17:    private:
    18:            int * itsAge;
    19:            int * itsWeight;
    20:       };
    21:
    22:       SimpleCat::SimpleCat()
    23:       {
    24:            itsAge = new int(2);
    25:            itsWeight = new int(5);
    26:       }
    27:
    28:       SimpleCat::~SimpleCat()
    29:       {
    30:            delete itsAge;
    31:            delete itsWeight;
    32:       }
    33:
    34:       int main()
    35:       {
    36:              SimpleCat *Frisky = new SimpleCat;
    37:              cout << "Frisky is " << Frisky->GetAge() << " years old\n";
    38:              Frisky->SetAge(5);
    39:              cout << "Frisky is " << Frisky->GetAge() << " years old\n";
    40:              delete Frisky;
    41:       return 0;
    42: }

    Output: Frisky is 2 years old
    Frisky is 5 years old

Analysis: The class `SimpleCat` is declared to have two member variables--both of which are pointers to integers--on lines 14 and 15. The constructor (lines 22-26) initializes the pointers to memory on the free store and to the default values.
The destructor (lines 28-32) cleans up the allocated memory. Because this is the destructor, there is no point in assigning these pointers to `null`, as they will no longer be accessible. This is one of the safe places to break the rule that deleted pointers should be assigned to `null`, although following the rule doesn't hurt.

The calling function (in this case, `main()`) is unaware that `itsAge` and `itsWeight` are point-ers to memory on the free store. `main()` continues to call `GetAge()` and `SetAge()`, and the details of the memory management are hidden in the implementation of the class--as they should be.

When `Frisky` is deleted in line 40, its destructor is called. The destructor deletes each of its member pointers. If these, in turn, point to objects of other user-defined classes, their destructors are called as well.

### The this Pointer

Every class member function has a hidden parameter: the `this` pointer. `this` points to the individual object. Therefore, in each call to `GetAge()` or `SetAge()`, the `this` pointer for the object is included as a hidden parameter.

It is possible to use the `this` pointer explicitly, as Listing 8.8 illustrates.

Listing 8.8. Using the this pointer.

    1:      // Listing 8.8
    2:      // Using the this pointer
    3:
    4:      #include <iostream.h>
    5:
    6:      class Rectangle
    7:      {
    8:      public:
    9:           Rectangle();
    10:           ~Rectangle();
    11:           void SetLength(int length) { this->itsLength = length; }
    12:           int GetLength() const { return this->itsLength; }
    13:
    14:           void SetWidth(int width) { itsWidth = width; }
    15:           int GetWidth() const { return itsWidth; }
    16:
    17:      private:
    18:           int itsLength;
    19:           int itsWidth;
    20:      };
    21:
    22:      Rectangle::Rectangle()
    23:      {
    24:          itsWidth = 5;
    25:          itsLength = 10;
    26:      }
    27:      Rectangle::~Rectangle()
    28:      {}
    29:
    30:      int main()
    31:      {
    32:           Rectangle theRect;
    33:           cout << "theRect is " << theRect.GetLength() << " feet long.\n";
    34:           cout << "theRect is " << theRect.GetWidth() << " feet wide.\n";
    35:           theRect.SetLength(20);
    36:           theRect.SetWidth(10);
    37:           cout << "theRect is " << theRect.GetLength()<< " feet long.\n";
    38:           cout << "theRect is " << theRect.GetWidth()<< " feet wide.\n";
    39:      return 0;
    40: }

    Output: theRect is 10 feet long.
    theRect is 5 feet long.
    theRect is 20 feet long.
    theRect is 10 feet long.

Analysis: The `SetLength()` and `GetLength()` accessor functions explicitly use the `this` pointer to access the member variables of the `Rectangle` object. The `SetWidth` and `GetWidth` accessors do not. There is no difference in their behavior, although the syntax is easier to understand.
If that were all there was to the `this` pointer, there would be little point in bothering you with it. The `this` pointer, however, is a pointer; it stores the memory address of an object. As such, it can be a powerful tool.

You'll see a practical use for the `this` pointer on Day 10, "Advanced Functions," when operator overloading is discussed. For now, your goal is to know about the `this` pointer and to understand what it is: a pointer to the object itself.

You don't have to worry about creating or deleting the `this` pointer. The compiler takes care of that.

### Stray or Dangling Pointers

One source of bugs that are nasty and difficult to find is stray pointers. A stray pointer is created when you call `delete` on a pointer--thereby freeing the memory that it points to--and later try to use that pointer again without reassigning it.

It is as though the Acme Mail Order company moved away, and you still pressed the programmed button on your phone. It is possible that nothing terrible happens--a telephone rings in a deserted warehouse. Perhaps the telephone number has been reassigned to a munitions factory, and your call detonates an explosive and blows up your whole city!

In short, be careful not to use a pointer after you have called `delete` on it. The pointer still points to the old area of memory, but the compiler is free to put other data there; using the pointer can cause your program to crash. Worse, your program might proceed merrily on its way and crash several minutes later. This is called a time bomb, and it is no fun. To be safe, after you delete a pointer, set it to `null` (`0`). This disarms the pointer.

> NOTE: Stray pointers are often called wild pointers or dangling pointers.

Listing 8.9 illustrates creating a stray pointer.

> WARNING: This program intentionally creates a stray pointer. Do NOT run this program--it will crash, if you are lucky.

Listing 8.9. Creating a stray pointer.

    1:     // Listing 8.9
    2:     // Demonstrates a stray pointer
    3:     typedef unsigned short int USHORT;
    4:     #include <iostream.h>
    5:
    6:     int main()
    7:     {
    8:        USHORT * pInt = new USHORT;
    9:        *pInt = 10;
    10:       cout << "*pInt: " << *pInt << endl;
    11:       delete pInt;
    12:       pInt = 0;
    13:       long * pLong = new long;
    14:       *pLong = 90000;
    15:       cout << "*pLong: " << *pLong << endl;
    16:
    17:       *pInt = 20;      // uh oh, this was deleted!
    18:
    19:       cout << "*pInt: " << *pInt  << endl;
    20:       cout << "*pLong: " << *pLong  << endl;
    21:       delete pLong;
    22:    return 0;
    23: }

    Output: *pInt:   10
    *pLong:  90000
    *pInt:   20
    *pLong:  65556
    Null pointer assignment

(Your output may look different.)

Analysis: Line 8 declares `pInt` to be a pointer to `USHORT`, and `pInt` is pointed to newly allocated memory. Line 9 puts the value `10` in that memory, and line 10 prints its value. After the value is printed, `delete` is called on the pointer. `pInt` is now a stray, or dangling, pointer.
Line 13 declares a new pointer, `pLong`, which is pointed at the memory allocated by `new`.
Line 14 assigns the value `90000` to `pLong`, and line 15 prints its value.

Line 17 assigns the value `20` to the memory that `pInt` points to, but `pInt` no longer points anywhere that is valid. The memory that `pInt` points to was freed by the call to `delete`, so assigning a value to that memory is certain disaster.

Line 19 prints the value at `pInt`. Sure enough, it is `20`. Line 20 prints `20`, the value at `pLong`; it has suddenly been changed to `65556`. Two questions arise:
1. How could `pLong`'s value change, given that `pLong` wasn't touched?
2. Where did the 20 go when `pInt` was used in line 17?
As you might guess, these are related questions. When a value was placed at `pInt` in line 17, the compiler happily placed the value `20` at the memory location that `pInt` previously pointed to. However, because that memory was freed in line 11, the compiler was free to reassign it. When `pLong` was created in line 13, it was given `pInt`'s old memory location. (On some computers this may not happen, depending on where in memory these values are stored.) When the value `20` was assigned to the location that `pInt` previously pointed to, it wrote over the value pointed to by `pLong`. This is called "stomping on a pointer." It is often the unfortunate outcome of using a stray pointer.
This is a particularly nasty bug, because the value that changed wasn't associated with the stray pointer. The change to the value at `pLong` was a side effect of the misuse of `pInt`. In a large program, this would be very difficult to track down.
Just for fun, here are the details of how 65,556 got into that memory address:

  1. `pInt` was pointed at a particular memory location, and the value `10` was assigned.
  2. `delete` was called on `pInt`, which told the compiler that it could put something else at that location. Then `pLong` was assigned the same memory location.
  3. The value `90000` was assigned to `*pLong`. The particular computer used in this example stored the four-byte value of 90,000 (00 01 5F 90) in byte-swapped order. Therefore, it was stored as 5F 90 00 01.
  4. `pInt` was assigned the value `20`--or 00 14 in hexadecimal notation. Because `pInt` still pointed to the same address, the first two bytes of `pLong` were overwritten, leaving 00 14 00 01.
  5. The value at `pLong` was printed, reversing the bytes back to their correct order of 00 01 00 14, which was translated into the DOS value of `65556`.

  DO use `new` to create objects on the free store. DO use `delete` to destroy objects on the free store and to return their memory. DON'T forget to balance all `new` statements with a `delete` statement. DON'T forget to assign `null` (`0`) to all pointers that you call `delete` on. DO check the value returned by `new`.

### const Pointers

You can use the keyword `const` for pointers before the type, after the type, or in both places. For example, all of the following are legal declarations:

    const int * pOne;
    int * const pTwo;
    const int * const pThree;

`pOne` is a pointer to a constant integer. The value that is pointed to can't be changed.

`pTwo` is a constant pointer to an integer. The integer can be changed, but `pTwo` can't point to anything else.

`pThree` is a constant pointer to a constant integer. The value that is pointed to can't be changed, and `pThree` can't be changed to point to anything else.

The trick to keeping this straight is to look to the right of the keyword `const` to find out what is being declared constant. If the type is to the right of the keyword, it is the value that is constant. If the variable is to the right of the keyword `const`, it is the pointer variable itself that is constant.

    const int * p1;  // the int pointed to is constant
    int * const p2;  // p2 is constant, it can't point to anything else

#### const Pointers and const Member Functions

On Day 6, "Basic Classes," you learned that you can apply the keyword `const` to a member function. When a function is declared `const`, the compiler flags as an error any attempt to change data in the object from within that function.

If you declare a pointer to a `const` object, the only methods that you can call with that pointer are `const` methods. Listing 8.10 illustrates this.

Listing 8.10. Using pointers to const objects.

    1:      // Listing 8.10
    2:      // Using pointers with const methods
    3:
    4:      #include <iostream.h>
    5:
    6:      class Rectangle
    7:      {
    8:      public:
    9:           Rectangle();
    10:           ~Rectangle();
    11:           void SetLength(int length) { itsLength = length; }
    12:           int GetLength() const { return itsLength; }
    13:
    14:           void SetWidth(int width) { itsWidth = width; }
    15:           int GetWidth() const { return itsWidth; }
    16:
    17:      private:
    18:           int itsLength;
    19:           int itsWidth;
    20:      };
    21:
    22:      Rectangle::Rectangle():
    23:      itsWidth(5),
    24:      itsLength(10)
    25:      {}
    26:
    27:      Rectangle::~Rectangle()
    28:      {}
    29:
    30:      int main()
    31:      {
    32:           Rectangle* pRect =  new Rectangle;
    33:           const Rectangle * pConstRect = new Rectangle;
    34:           Rectangle * const pConstPtr = new Rectangle;
    35:
    36:           cout << "pRect width: " << pRect->GetWidth() << " feet\n";
    37:           cout << "pConstRect width: " << pConstRect->GetWidth() << " feet\n";
    38:           cout << "pConstPtr width: " << pConstPtr->GetWidth() << " feet\n";
    39:
    40:           pRect->SetWidth(10);
    41:           // pConstRect->SetWidth(10);
    42:           pConstPtr->SetWidth(10);
    43:
    44:           cout << "pRect width: " << pRect->GetWidth() << " feet\n";
    45:           cout << "pConstRect width: " << pConstRect->GetWidth() << " feet\n";
    46:           cout << "pConstPtr width: " << pConstPtr->GetWidth() << " feet\n";
    47:      return 0;
    48: }

    Output: pRect width: 5 feet
    pConstRect width: 5 feet
    pConstPtr width: 5 feet
    pRect width: 10 feet
    pConstRect width: 5 feet
    pConstPtr width: 10 feet

Analysis: Lines 6-20 declare `Rectangle`. Line 15 declares the `GetWidth()` member method `const`. Line 32 declares a pointer to `Rectangle`. Line 33 declares `pConstRect`, which is a pointer to a constant `Rectangle`. Line 34 declares `pConstPtr`, which is a constant pointer to `Rectangle`.
Lines 36-38 print their values.

In line 40, `pRect` is used to set the width of the rectangle to `10`. In line 41, `pConstRect` would be used, but it was declared to point to a constant `Rectangle`. Therefore, it cannot legally call a non-`const` member function; it is commented out. In line 38, `pConstPtr` calls `SetAge()`. `pConstPtr` is declared to be a constant pointer to a rectangle. In other words, the pointer is constant and cannot point to anything else, but the rectangle is not constant.

#### const this Pointers

When you declare an object to be `const`, you are in effect declaring that the `this` pointer is a pointer to a `const` object. A `const` `this` pointer can be used only with `const` mem- ber functions.

Constant objects and constant pointers will be discussed again tomorrow, when references to constant objects are discussed.

> DO protect objects passed by reference with `const` if they should not be changed. DO pass by reference when the object can be changed. DO pass by value when small objects should not be changed.

### Summary

Pointers provide a powerful way to access data by indirection. Every variable has an address, which can be obtained using the `address of` operator (`&`). The address can be stored in a pointer.

Pointers are declared by writing the type of object that they point to, followed by the indirection operator (`*`) and the name of the pointer. Pointers should be initialized to point to an object or to `null` (`0`).

You access the value at the address stored in a pointer by using the indirection operator (`*`). You can declare `const` pointers, which can't be reassigned to point to other objects, and pointers to `const` objects, which can't be used to change the objects to which they point.

To create new objects on the free store, you use the `new` keyword and assign the address that is returned to a pointer. You free that memory by calling the `delete` keyword on the pointer. `delete` frees the memory, but it doesn't destroy the pointer. Therefore, you must reassign the pointer after its memory has been freed.

### Q&A

  Q. Why are pointers so important?
  A. Today you saw how pointers are used to hold the address of objects on the free store and how they are used to pass arguments by reference. In addition, on Day 13, "Polymorphism," you'll see how pointers are used in class polymorphism.
  Q. Why should I bother to declare anything on the free store?
  A. Objects on the free store persist after the return of a function. Additionally, the ability to store objects on the free store enables you to decide at runtime how many objects you need, instead of having to declare this in advance. This is explored in greater depth tomorrow.
  Q. Why should I declare an object const if it limits what I can do with it?
  A. As a programmer, you want to enlist the compiler in helping you find bugs. One serious bug that is difficult to find is a function that changes an object in ways that aren't obvious to the calling function. Declaring an object `const` prevents such changes.

### Workshop

The Workshop provides quiz questions to help you solidify your understanding of the material covered and exercises to provide you with experience in using what you've learned. Try to answer the quiz and exercise questions before checking the answers in Appendix D, and make sure you understand the answers before continuing to the next chapter.

#### Quiz

  1. What operator is used to determine the address of a variable?
  2. What operator is used to find the value stored at an address held in a pointer?
  3. What is a pointer?
  4. What is the difference between the address stored in a pointer and the value at that address?
  5. What is the difference between the indirection operator and the `address of` operator?
  6. What is the difference between `const int * ptrOne` and `int * const ptrTwo`?

#### Exercises

  1. What do these declarations do?
    a. `int * pOne;`
    b. `int vTwo;`
    c. `int * pThree = &vTwo;`
  2. If you have an `unsigned short` variable named `yourAge`, how would you declare a pointer to manipulate `yourAge`?
  3. Assign the value `50` to the variable `yourAge` by using the pointer that you declared in Exercise 2.
  4. Write a small program that declares an integer and a pointer to integer. Assign the address of the integer to the pointer. Use the pointer to set a value in the integer variable.
  5. BUG BUSTERS: What is wrong with this code?

    #include <iostream.h>
    int main()
    {      int *pInt;
         *pInt = 9;
         cout << "The value at pInt: " << *pInt;
         return 0;
    }

  6. BUG BUSTERS: What is wrong with this code?

    int main()
    {
        int SomeVariable = 5;
        cout << "SomeVariable: " << SomeVariable << "\n";
        int *pVar = & SomeVariable;
        pVar = 9;
        cout << "SomeVariable: " << *pVar << "\n";
    return 0;
    }