C Pointer to Pointer
In this page:
data_type **pointer_to_pointer = &pointer_name;
**pointer_to_pointer;
What is a Pointer to a Pointer?
This chain is exactly the mechanism argv uses in main(int argc, char **argv) -- argv is a pointer to an array of pointers, where each element points to one command-line argument string.
Example: What is a Pointer to a Pointer?
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Program execution starts in main()
int main() {
char *args[2] = {"prog", "arg1"};
char **argv = args;
// Print formatted text to the screen
printf("%s", argv[1]);
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Declaring and Initializing
The declaration mirrors the double-pointer syntax you'd use for any type: int **pptr for pointers to int pointers, char **names for arrays of string pointers, and so on -- the type before the asterisks must match what's ultimately being pointed to.
Example: Declaring and Initializing
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Program execution starts in main()
int main() {
// Declare x and set it to 5
int x = 5;
int *ptr = &x;
int **pptr = &ptr;
// Print formatted text to the screen
printf("%d", **pptr);
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Dereferencing Once
This gives you an intermediate address in the chain -- if pptr points to ptr, then *pptr gives you ptr's value, which is itself an address (the one ptr points to), not yet the final data.
Example: Dereferencing Once
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Program execution starts in main()
int main() {
// Declare x and set it to 5
int x = 5;
int *ptr = &x;
int **pptr = &ptr;
// Print formatted text to the screen
printf("%p", (void*)*pptr);
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Dereferencing Twice
This is the operation that finally reaches the actual stored data at the bottom of the indirection chain, skipping past both layers of pointer addresses to get to the real value.
Example: Dereferencing Twice
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Program execution starts in main()
int main() {
// Declare x and set it to 5
int x = 5;
int *ptr = &x;
int **pptr = &ptr;
// Print formatted text to the screen
printf("%d", **pptr);
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Modifying Pointers in Functions
This pattern is common in functions that allocate memory and need to hand the new address back to the caller through a parameter, since a single pointer parameter would only let you modify a copy of the caller's pointer, not the original.
Example: Modifying Pointers in Functions
// Include standard input/output (printf, scanf)
#include <stdio.h>
void allocate(int **out) {
static int value = 10;
*out = &value;
}
// Program execution starts in main()
int main() {
int *ptr = NULL;
allocate(&ptr);
// Print formatted text to the screen
printf("%d", *ptr);
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
- Dereferencing only once and treating
*ppas the value, when it is still a pointer. - Using a pointer to a pointer before assigning it a valid address.
- Losing track of levels, for example passing
&pwherepis expected, which gives a type mismatch.
- A pointer stores a memory address, and pointer arithmetic moves through memory one element at a time.
- Pointers connect closely to arrays and functions, letting functions work directly with the caller's data.
- Null, void, and double pointers cover special cases, such as empty pointers, generic pointers, and pointers to pointers.
Chapter Quiz — Complete all 9 topics to unlock
0/9 topics done
Complete these topics first: