Double Pointers
Let us study the below example:
File: d1.cpp
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
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; }