- C Programming Tutorial
- C - Home
- Basics of C
- C - Overview
- C - Features
- C - History
- C - Environment Setup
- C - Program Structure
- C - Hello World
- C - Compilation Process
- C - Comments
- C - Tokens
- C - Keywords
- C - Identifiers
- C - User Input
- C - Basic Syntax
- C - Data Types
- C - Variables
- C - Integer Promotions
- C - Type Conversion
- C - Type Casting
- C - Booleans
- Constants and Literals in C
- C - Constants
- C - Literals
- C - Escape sequences
- C - Format Specifiers
- Operators in C
- C - Operators
- C - Arithmetic Operators
- C - Relational Operators
- C - Logical Operators
- C - Bitwise Operators
- C - Assignment Operators
- C - Unary Operators
- C - Increment and Decrement Operators
- C - Ternary Operator
- C - sizeof Operator
- C - Operator Precedence
- C - Misc Operators
- Decision Making in C
- C - Decision Making
- C - if statement
- C - if...else statement
- C - nested if statements
- C - switch statement
- C - nested switch statements
- Loops in C
- C - Loops
- C - While loop
- C - For loop
- C - Do...while loop
- C - Nested loop
- C - Infinite loop
- C - Break Statement
- C - Continue Statement
- C - goto Statement
- Functions in C
- C - Functions
- C - Main Function
- C - Function call by Value
- C - Function call by reference
- C - Nested Functions
- C - Variadic Functions
- C - User-Defined Functions
- C - Callback Function
- C - Return Statement
- C - Recursion
- Scope Rules in C
- C - Scope Rules
- C - Static Variables
- C - Global Variables
- Arrays in C
- C - Arrays
- C - Properties of Array
- C - Multi-Dimensional Arrays
- C - Passing Arrays to Function
- C - Return Array from Function
- C - Variable Length Arrays
- Pointers in C
- C - Pointers
- C - Pointers and Arrays
- C - Applications of Pointers
- C - Pointer Arithmetics
- C - Array of Pointers
- C - Pointer to Pointer
- C - Passing Pointers to Functions
- C - Return Pointer from Functions
- C - Function Pointers
- C - Pointer to an Array
- C - Pointers to Structures
- C - Chain of Pointers
- C - Pointer vs Array
- C - Character Pointers and Functions
- C - NULL Pointer
- C - void Pointer
- C - Dangling Pointers
- C - Dereference Pointer
- C - Near, Far and Huge Pointers
- C - Initialization of Pointer Arrays
- C - Pointers vs. Multi-dimensional Arrays
- Strings in C
- C - Strings
- C - Array of Strings
- C - Special Characters
- C Structures and Unions
- C - Structures
- C - Structures and Functions
- C - Arrays of Structures
- C - Self-Referential Structures
- C - Lookup Tables
- C - Dot (.) Operator
- C - Enumeration (or enum)
- C - Structure Padding and Packing
- C - Nested Structures
- C - Anonymous Structure and Union
- C - Unions
- C - Bit Fields
- C - Typedef
- File Handling in C
- C - Input & Output
- C - File I/O (File Handling)
- C Preprocessors
- C - Preprocessors
- C - Pragmas
- C - Preprocessor Operators
- C - Macros
- C - Header Files
- Memory Management in C
- C - Memory Management
- C - Memory Address
- C - Storage Classes
- Miscellaneous Topics
- C - Error Handling
- C - Variable Arguments
- C - Command Execution
- C - Math Functions
- C - Static Keyword
- C - Random Number Generation
- C - Command Line Arguments
- C Programming Resources
- C - Questions & Answers
- C - Quick Guide
- C - Cheat Sheet
- C - Useful Resources
- C - Discussion
Pointer to Pointer (Double Pointer) in C
What is a Double Pointer in C?
A pointer to pointer which is also known as a double pointer in C is used to store the address of another pointer.
A variable in C that stores the address of another variable is known as a pointer. A pointer variable can store the address of any type including the primary data types, arrays, struct types, etc. Likewise, a pointer can store the address of another pointer too, in which case it is called "pointer to pointer" (also called "double pointer").
A "pointer to a pointer" is a form of multiple indirection or a chain of pointers. Normally, a pointer contains the address of a variable. When we define a "pointer to a pointer", the first pointer contains the address of the second pointer, which points to the location that contains the actual value as shown below −
Declaration of Pointer to a Pointer
The declaration of a pointer to pointer (double pointer) is similar to the declaration of a pointer, the only difference is that you need to use an additional asterisk (*) before the pointer variable name.
Example
For example, the following declaration declares a "pointer to a pointer" of type int −
int **var;
When a target value is indirectly pointed to by a "pointer to a pointer", accessing that value requires that the asterisk operator be applied twice.
Example of Pointer to Pointer (Double Pointer)
The following example demonstrates the declaration, initialization, and using pointer to pointer (double pointer) in C:
#include <stdio.h> int main() { // An integer variable int a = 100; // Pointer to integer int *ptr = &a; // Pointer to pointer (double pointer) int **dptr = &ptr; printf("Value of 'a' is : %d\n", a); printf("Value of 'a' using pointer (ptr) is : %d\n", *ptr); printf("Value of 'a' using double pointer (dptr) is : %d\n", **dptr); return 0; }
Output
Value of 'a' is : 100 Value of 'a' using pointer (ptr) is : 100 Value of 'a' using double pointer (dptr) is : 100
How Does a Normal Pointer Work in C?
Assume that an integer variable "a" is located at an arbitrary address 1000. Its pointer variable is "b" and the compiler allocates it the address 2000. The following image presents a visual depiction −
Let us declare a pointer to int type and store the address of an int variable in it.
int a = 10; int *b = &a;
The dereference operator fetches the value via the pointer.
printf("a: %d \nPointer to 'a' is 'b': %d \nValue at 'b': %d", a, b, *b);
Example
Here is the complete program that shows how a normal pointer works −
#include <stdio.h> int main(){ int a = 10; int *b = &a; printf("a: %d \nPointer to 'a' is 'b': %d \nValue at 'b': %d", a, b, *b); return 0; }
Output
It will print the value of int variable, its address, and the value obtained by the dereference pointer −
a: 10 Pointer to 'a' is 'b': 6422036 Value at 'b': 10
How Does a Double Pointer Work?
Let us now declare a pointer that can store the address of "b", which itself is a pointer to int type written as "int *".
Let's assume that the compiler also allocates it the address 3000.
Hence, "c" is a pointer to a pointer to int, and should be declared as "int **".
int **c = &b; printf("b: %d \nPointer to 'b' is 'c': %d \nValue at b: %d\n", b, c, *c);
You get the value of "b" (which is the address of "a"), the value of "c" (which is the address of "b:), and the dereferenced value from "c" (which is the address of "a") −
b: 6422036 Pointer to b is c: 6422024 Value at b: 6422036
Here, "c" is a double pointer. The first asterisk in its declaration points to "b" and the second asterisk in turn points to "a". So, we can use the double reference pointer to obtain the value of "a" from "c".
printf("Value of 'a' from 'c': %d", **c);
This should display the value of 'a' as 10.
Example
Here is the complete program that shows how a double pointer works −
#include <stdio.h> int main(){ int a = 10; int *b = &a; printf("a: %d \nAddress of 'a': %d \nValue at a: %d\n\n", a, b, *b); int **c = &b; printf("b: %d \nPointer to 'b' is c: %d \nValue at b: %d\n", b, c, *c); printf("Value of 'a' from 'c': %d", **c); return 0; }
Output
Run the code and check its output −
a: 10 Address of 'a': 1603495332 Value at a: 10 b: 1603495332 Pointer to 'b' is c: 1603495336 Value at b: 1603495332 Value of 'a' from 'c': 10
A Double Pointer Behaves Just Like a Normal Pointer
A "pointer to pointer" or a "double pointer" in C behaves just like a normal pointer. So, the size of a double pointer variable is always equal to a normal pointer.
We can check it by applying the sizeof operator to the pointers "b" and "c" in the above program −
printf("Size of b - a normal pointer: %d\n", sizeof(b)); printf("Size of c - a double pointer: %d\n", sizeof(c));
This shows the equal size of both the pointers −
Size of b - a normal pointer: 8 Size of c - a double pointer: 8
Note: The size and address of different pointer variables shown in the above examples may vary, as it depends on factors such as CPU architecture and the operating system. However, they will show consistent results.
Multilevel Pointers in C (Is a Triple Pointer Possible?)
Theoretically, there is no limit to how many asterisks can appear in a pointer declaration.
If you do need to have a pointer to "c" (in the above example), it will be a "pointer to a pointer to a pointer" and may be declared as −
int ***d = &c;
Mostly, double pointers are used to refer to a two−dimensional array or an array of strings.