Pointer to Pointer in C

Challenge Inside! : Find out where you stand! Try quiz, solve problems & win rewards!

Learn via video course

C++ Course: Learn the Essentials
C++ Course: Learn the Essentials
By Prateek Narang
Free
star5
Enrolled: 1000
C++ Course: Learn the Essentials
C++ Course: Learn the Essentials
Prateek Narang
Free
5
icon_usercirclecheck-01Enrolled: 1000
Start Learning

Overview

Similar to how a pointer variable in C can be used to access or modify the value of a variable in C, a pointer to pointer in C is used to access/modify the value of a pointer variable. Here, the "value" of the former pointer is as usual a memory address. So, using a pointer to the pointer aka a double pointer in C, we can make the previous pointer point to another memory location.

Scope

  • This article defines what is pointer to pointer in C, the syntax for declaring the same and also, a pointer to pointer example.
  • This article attempts to list a few scenarios where a pointer to a pointer in C might be useful.

Introduction

Whenever there is a requirement to use the memory address of a variable, it is quite usual to use a pointer variable to do so using the following syntax:

The following image illustrates the relation between ptr and var c pointer variable

Note that the pointer ptr is itself a variable and hence, it will be allocated some memory on the memory stack. Thus, it will have a memory address of its own. A pointer to a pointer in C or a double pointer will point to this memory address of the pointer.

We can also think about this in terms of levels :

  • Level 1 : Normal variable
  • Level 2 : Normal pointer to a variable
  • Level 3 : Double pointer (or pointer to a pointer)
  • Level 4 : Triple pointer (or pointer to pointer to pointer)
  • Level 5 : ...

The above list can be extended to further levels as and when required by the programmer.

A double pointer behaves in the same way as an ordinary pointer except that it will modify the value of the pointer that it is pointing to. In other words, the memory address stored in the ordinary pointer can be modified.

Declaring pointer to pointer in C

The syntax to declare a double pointer is

pointer_data_type **variable_name = &ordinary_pointer_variable;

Here, the initialization is optional. We can simply declare the double pointer variable and assign it a value later.

Syntax:

A double pointer should only point to an ordinary pointer. In case we attempt to do something like this

the compiler will generate the following warning

Size of pointer to pointer in C

Since a double pointer in C behaves similar to a normal pointer, the size of the double pointer variable and the size of the ordinary pointer variable are always equal. This can be verified using the following line:

Output:

Note: The output above depends on the type of machine in which the code is being executed. In other words, the size of a pointer is not fixed in C and it depends on different factors like OS and CPU architecture. Usually, for a 64-bit OS, the size is 8 bytes and for a 32-bit OS, the size is 4 bytes.

Reading pointer declarations in C

Before moving on to the usages of a double pointer, let's quickly understand how to identify and read pointer declarations in C. Consider the following example:

To read the above line, we'll start at the variable name and end at the basic datatype by proceeding from right to left :

  • First, we have the variable name, so we'll read that first as "double_ptr is".
  • The next character that we have to the left is *. Everytime, we encounter a *, we add the words "pointer to". So, the phrase now becomes "double_ptr is a pointer".
  • We again encounter a * to the left and so, we add the words "pointer to" again. So, the phrase now becomes "double_ptr is a pointer to a pointer ".
  • The only term remaining to the left is the datatype which we'll read as "integer variable". So, the overall phrase now becomes "double_ptr is a pointer to a pointer to an integer variable".

Diagrammatic representation of pointer to pointer in C

pointer to pointer in C Note that the above method could be extended to other pointer types as well. In other words, we can extend the reading guidelines for further levels of pointers as well. The previous example was about "Level 3 pointers" or double pointers. Here's an example of "Level 4 pointers" or triple pointers :

We can read the above line as:

  • First, we read the variable name as "ptr is".
  • Then, we have to choose between [10] and *. In such cases, we first consider the term to the right and then to the left. So, we'll prioritize [10] and read it as "array of 10". So, the phrase becomes "ptr is array of 10".
  • Then we move to the left and find three *'s. For every *, we add the words "a pointer to". So, the overall phrase becomes "ptr is array of 10 pointers to a pointer to pointer".
  • Then, we finally read the data type, and the final phrase becomes "ptr is array of 10 pointers to a pointer to pointer to float variable".

Examples of double pointers

Example 1: 2-D character array

We can store a string in C using a character pointer however, using a character double pointer in C, we can store a list of strings.

Why not use a 2D character array to do this? This can also be achieved using a 2D character array, but the size of all the strings is not necessarily equal and so we might end up wasting a lot of extra space. Thus, the double pointer method is more space efficient.

Note: The following method can be extended to other datatypes as well which have been explained in the subsequent examples.

The following code demonstrates how this can be done:

Output:

Example 2: Command line arguments in C

Whenever we want to use command line arguments in our C program, we need to provide these parameters to the main() function :

Note that we can also write the above statement as

but for now, let's address the double-pointer syntax version.

Here, argc (argument count) represents the number of arguments passed through the command line including the name of the program. Since argv (argument vector) is a double-character pointer, as discussed in the previous point, it will store a list of strings. More specifically, argv points to the strings passed as command line arguments (including the name of the program itself). The string at index 0, i.e., argv[0] is the name of the program and if the value of argc is positive, the arguments are pointed to by the indices from 1 to argc-1, i.e., argv[1], argv[2],...,argv[argc-1] The following example demonstrates how the command line arguments can be read.

Now, let's say we are executing the above program on a Linux machine using the terminal. This is how it would look like:

We have provided 4 arguments in the command line above while executing the program.

Output:

Example 3: Dynamic memory allocation using double pointer

Another convenient use of double pointer is if we want to dynamically allocate the memory for a pointer variable in a separate function and then use that pointer in the calling function. The following example shows how this can be done:

Output:

Example 4: 2-D arrays

Similar to a list of strings, double pointers can be used to create 2D arrays of other data types as well such as int, float, etc. The following snippet shows how this can be done:

Output:

Key Takeaways

  • We can use a pointer to pointer in C to alter the value of an ordinary pointer or to create variable-sized 2D arrays as shown in the Examples section.
  • A double pointer behaves similar to an ordinary pointer and occupies the same amount of space in the memory stack.

Conclusion

  • Double pointers in C are very powerful and can have many applications (as explained in the Examples section) apart from simple data manipulation.
  • In most cases, it is a personal preference whether to make use of a double pointer or use a workaround. However, in certain scenarios, the use of double-pointers becomes mandatory. One such example is if we want to store a list of variable-sized strings in a space efficient manner or if the size of a 2D array can change during the course of program execution.
  • To change the value of a double pointer, we can use a "triple" pointer, which is a pointer to a pointer to a pointer (eg. int ***triple_ptr). Similarly, to change the value of a triple pointer we can use a pointer to a pointer to a pointer to a pointer. In other words, to change the value of a "Level X" variable, we can use a "Level X+1" pointer. Thus, this concept can be extended to further levels.