I am hoping this article would help beginners. It describes how memory can be dynamically allocated, how values are assigned or retrieved, and how memory is freed up for 'pointer to pointer' variables.
Pointers, Reference operator (&), and Dereference operator (*)
Before discussing about 'pointer to pointer' variables, we will see what a pointer variable is and what the reference operator (
&) and dereference operator (
*) are used for.
A pointer variable can be declared as:
The above declaration means that the pointer variable "
a" can hold the address of memory allocated to an integer variable.
In the above sample code, the reference operator (
&) is used to refer the address of the memory location assigned for the integer variable '
val'. Also, the dereference operator (
*) is used to point to the content of the memory location whose address is held by the pointer variable '
printf statement prints '10', and the second
printf statement prints '15'.
Pointer to pointer variables
A pointer to pointer variable can hold the address of another pointer variable. It can be declared as:
Think of the memory to be allocated to a pointer to pointer variable as two dimensional. It has 'rows' and 'columns'; i.e., if the size is m x n, there will be 'm' rows, and for each row, there will be 'n' columns.
- First, you have to allocate memory for 'm' rows.
- Secondly, you have to allocate 'n' columns for each of the 'm' rows.
We will take an example for allocating memory to a pointer to pointer to float values. Let the number of rows be '4' and the number of columns '3'.
float_values = (float**)malloc(4 *sizeof(float*));
for(int i=0; i<4; i++)
*(float_values+i) = (float*)malloc(3 *sizeof(float));
We need to know how we can access each location before assigning values to them.
There are two ways to access these two dimensional memory locations.
- Use the
 operator in the same way we use for two dimensional arrays.
float_values[i][j] = val;
- Use the pointer operator ("
*(*(float_values+i)+j) = val;
Display or retrieve values
For retrieving, we can use any of the two operators which we used for assigning values. An example for using the "
*" operator is given below.
for(int i=0; i<2; i++)
for(int j=0; j<3; j++)
Freeing up the allocated memory
We should not forget to free the memory which we have allocated dynamically, starting from the lowest level, i.e., in the reverse order of allocations. If we free up the higher level pointers first, the lower level pointers would be lost and we would not be able to free up the memory allocated to those pointers. This would lead to memory leaks. Given below is how we should free up memory:
for(int i = 0; i < 4; i++)