Home C++ Introduction Decisions Loops Input/Output Functions Stack and Heap References Arrays Searching and Sorting Recursion Pointers Character and Strings Structures Classes Inheritance Exceptions Templatess STL Modern C++ Misc Books ----

Double Pointers


Let us study the below example:
File: d1.cpp
/* Double pointer program */

#include<stdio.h>
#include <stdlib.h>
#include <iostream>

using namespace std ;

int main(int argc , char** args)
{
    int x1 = 100 ;
    int x2 = 200 ;
    int* ptr1 ;
    int** doublePtr ;


    ptr1 = &x1 ;
    doublePtr = &ptr1 ;

    cout << *ptr1 << endl ;
    //2 Levels of indirection
    cout << **doublePtr << endl ;
    *doublePtr = &x2 ;

    cout << **doublePtr << endl ;
    cout << *ptr1 << endl ;

    return(1) ;

}
/*

RAM

x1            0   100

x2            5   200

ptr1          10  0 --> 5

doublePtr 15 10

*/

Output:

100

100

200

200

In the above example we have a pointer "ptr1". A pointer
variable will always hold an address. This is true
regardless of what the pointer type will be. It is always
helpful to draw a diagram in the RAM to understand pointers.
We do not need the exact RAM address that will be assigned
when the program is run. We need a conceptual understanding
and the diagram can help with that. Initially the pointer
"ptr1" holds the address of the variable "x1" . We define
the double pointer with the declaration:

int** doublePtr ;

What is the above stating ? The "doublePtr" is also a
pointer. It occupies space in the memory and it's value
is an address.

ptr1 = & x1

We have the "ptr1 " holding the address of the variable
x1 . In our conceptual diagram x1 is at the address 0
holding the value 100 and x2 is at the address 5 holding
the value 200 . So the "ptr1" variable is now going to
hold the address 0 . Remember "ptr1" is also a variable
and thus resides at an address . In our example "ptr1"
is at the address 10 .

 doublePtr = &ptr1 ;

In the above line we are taking the address of "ptr1" and
assigning it to "doublePtr". The "doublePtr"  is also a
pointer and it contains an address .

However when we apply the operation of  "*doublePtr"
We do not get an integer value. Instead we get another
address. In the above diagram if we do "*doublePtr" we
follow the "10" to the pointer variable "ptr1" where we
get the value "0" . This is yet another address and we
could follow it to where x1 is by another "*" . Using
the notation "**doublePtr" we can obtain the value of
the "x1" variable which is 100 .

Next we have the statement

cout << *ptr1 << endl ;

The above statement states that we look up the address in
the "ptr1" variable which is "0" and follow that to obtain
the value of "x1" which is 100 .

cout << **doublePtr << endl ;

What the "**" does is 2 levels of indirection.
The first "*doublePtr" gives us "0" which is the
address of x1 that ptr1 stores. Recall that "doublePtr"
itself stores the address 10 ( address of ptr1 ) and
with "*" we are following that. Now that we have 0 we
do another "*" ( we have 2 stars in **doublePtr ) .
Following 0 leads us to the value of x1 which is 100
and that gets printed out.

now we have the value of "x2" printed out and that is 200 .
Exercises
1) In the example above what do &doublePtr, doublePtr and *doublePtr have for values in the conceptual diagram ?
2)
Run the following program on your computer and draw the RAM diagram to understand the output:
Change the value of "num" by using the "ptr1" and also by using "double_ptr" .
File: ex5.cpp
#include <iostream>

using namespace std ;
int main()
{
    int num  =   100  ;
    //A normal pointer ptr1
    int *ptr1;
    //This pointer ptr1 is a double pointer
    int **double_ptr;
    /* Assigning the address of variable num to the       * pointer ptr1       */
    ptr1 = &num   ;
    /* Assigning the address of pointer ptr1 to the       * pointer-to-pointer double_ptr       */
    double_ptr = &ptr1;        /* Possible ways to find value of variable num*/

    printf("\n Value of num is: %d", num);
    printf("\n Value of num using ptr1 is: %d", *ptr1);
    printf("\n Value of num using double_ptr is: %d", **double_ptr);


    /*Possible ways to find address of num*/
    printf("\n Address of num is: %p", &num);
    printf("\n Address of num using ptr1 is: %p", ptr1);
    printf("\n Address of num using double_ptr is: %p", *double_ptr);

    /*Find value of pointer*/
    printf("\n Value of Pointer ptr1 is: %p", ptr1);
    printf("\n Value of Pointer ptr1 using double_ptr is: %p", *double_ptr);

    /*Ways to find address of pointer*/
    printf("\n Address of Pointer ptr1 is:%p",&ptr1);
    printf("\n Address of Pointer ptr1 using double_ptr is:%p",double_ptr);


    /*Double pointer value and address*/
    printf("\n Value of Pointer double_ptr is:%p",double_ptr);
    printf("\n Address of Pointer double_ptr is:%p",&double_ptr);

    return 0;
}