Basics of Integer Triple Pointers ===================================== In this section, you are going to learn .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to use Triple Pointers ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Basics of Triple Pointers * :ref:`1 Triple Pointer 1 Double Pointer, 1 Single Pointer : Simple variables ` * :ref:`1 Triple Pointer, 1 Double Pointer, 1 Single Pointer : With Single pointer pointing to arrays ` * :ref:`1 Triple Pointer, 1 Double Pointer, 1 Single Pointer : With Single pointer heap allocation ` * :ref:`1 Triple Pointer, 1 Double Pointer : With two heap allocations : Create 1x1 array ` * :ref:`1 Triple Pointer, 1 Double Pointer : With two heap allocations : Create 1x10 array ` * :ref:`1 Triple Pointer, 1 Double Pointer : Double Pointer Pointing to array of single pointers : Static ` * :ref:`1 Triple Pointer, 1 Double Pointer : Pointing to array of single pointers : Dynamic ` .. _basic_ptr_int_tp_sp_ex1: .. tab-set:: .. tab-item:: 1 Triple Pointer, 1 Double Pointer, 1 Single Pointer : Simple variables * Step 1 : Define a Integer .. code-block:: c int c = 65; * Step 2 : Define a Single pointer .. code-block:: c int *sp = &c; OR .. code-block:: c int *sp; sp = &c; * Step 3 : Define a Double pointer .. code-block:: c int **dp = &sp; OR .. code-block:: c int **dp; dp = &sp; * Step 4 : Define a Triple pointer .. code-block:: c int ***tp = &dp; OR .. code-block:: c int ***tp; tp = &dp; * Step 5 : Access user data (in this case integer) using single pointer .. code-block:: c printf("*sp = %d\n", *sp); * Step 6 : Access user data (in this case integer) using double pointer .. code-block:: c printf("**dp = %d\n", **dp); * Step 7 : Access user data (in this case integer) using triple pointer .. code-block:: c printf("***tp = %d\n", ***tp); * Step 8 : Use \*\*tp to point to new user data (in this case variable d) .. code-block:: c **tp = &d; * Step 9 : Now user data can be accessed using \*sp, \*\*dp, \*\*\*tp which prints value of integer d .. code-block:: c printf("d = %d\n", d); printf("d = %d\n", *sp); printf("d = %d\n", **dp); printf("d = %d\n", ***tp); * See full program below .. code-block:: c #include int main(void) { int c = 65; int *sp = &c; int **dp = &sp; int ***tp = &dp; printf("c = %d\n", c); printf("*sp = %d\n", *sp); printf("**dp = %d\n", **dp); printf("***tp = %d\n", ***tp); int d = 100; **tp = &d; printf("d = %d\n", d); printf("*sp = %d\n", *sp); printf("**dp = %d\n", **dp); printf("***tp = %d\n", ***tp); return 0; } * Output is as below .. code-block:: c c = 65 *sp = 65 **dp = 65 ***tp = 65 d = 100 *sp = 100 **dp = 100 ***tp = 100 .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Summary of Naming conventions Consider .. code-block:: c int ***tp; then * tp is a triple pointer * \*tp is a double pointer * \*\*tp is a single pointer * \*\*\*tp is user data .. _basic_ptr_int_tp_sp_ex2: .. tab-set:: .. tab-item:: 1 Triple Pointer, 1 Double Pointer, 1 Single Pointer : With Single pointer pointing to arrays * Step 1 : Define a single dimension array of integers .. code-block:: c int arr[5] = {1, 2, 3, 4, 5}; * Step 2 : Define a single pointer .. code-block:: c int *sp = arr; OR .. code-block:: c int *sp; sp = arr; OR .. code-block:: c int *sp; sp = &arr[0]; * Step 3 : Define a double pointer .. code-block:: c int **dp = &sp; OR .. code-block:: c int **dp; dp = &sp; * Step 4 : Define a Triple pointer .. code-block:: c int ***tp = &dp; OR .. code-block:: c int ***tp; tp = &dp; * Step 5 : Access user data (in this case array of integers) using single pointer variable ``arr`` .. code-block:: c for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++) { printf("arr[%d] = %d\n", i, arr[i]); } * Step 5 : Access user data (in this case array of integers) using single pointer variable ``sp`` .. code-block:: c for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++) { printf("sp[%d] = %d\n", i, sp[i]); } * Step 6 : Access user data (in this case array of integers) using double pointer variable ``dp`` .. code-block:: c for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++) { printf("(*dp)[%d] = %d\n", i, (*dp)[i]); } * Step 7 : Access user data (in this case array of integers) using triple pointer variable ``tp`` .. code-block:: c for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++) { printf("(**tp)[%d] = %d\n", i, (**tp)[i]); } .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Note ``*dp`` should be called as single pointer because of below equations * dp = &sp; * \*dp = sp; .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Note ``**tp`` should be called as single pointer because of below equations * tp = &dp; * \*tp = dp; * \*tp = &sp; * \*\*tp = sp; * See full program below .. code-block:: c #include int main(void) { int arr[5] = {1, 2, 3, 4, 5}; int *sp = arr; int **dp = &sp; int ***tp = &dp; for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++) { printf("arr[%d] = %d\n", i, arr[i]); } for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++) { printf("sp[%d] = %d\n", i, sp[i]); } for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++) { printf("(*dp)[%d] = %d\n", i, (*dp)[i]); } for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++) { printf("(**tp)[%d] = %d\n", i, (**tp)[i]); } return 0; } * Output is as below .. code-block:: c arr[0] = 1 arr[1] = 2 arr[2] = 3 arr[3] = 4 arr[4] = 5 sp[0] = 1 sp[1] = 2 sp[2] = 3 sp[3] = 4 sp[4] = 5 (*dp)[0] = 1 (*dp)[1] = 2 (*dp)[2] = 3 (*dp)[3] = 4 (*dp)[4] = 5 (**tp)[0] = 1 (**tp)[1] = 2 (**tp)[2] = 3 (**tp)[3] = 4 (**tp)[4] = 5 .. _basic_ptr_int_tp_sp_ex3: .. tab-set:: .. tab-item:: 1 Triple Pointer, 1 Double Pointer, 1 Single Pointer : With Single pointer heap allocation * Step 1 : Define a single pointer .. code-block:: c int *sp; * Step 2 : Allocate heap memory to single pointer .. code-block:: c sp = malloc(5 * sizeof(int)); * Step 3 : Copy User data to heap memory .. code-block:: c sp[0] = 100; sp[1] = 200; sp[2] = 300; sp[3] = 400; sp[4] = 500; * Step 4 : Define a double pointer .. code-block:: c int **dp; dp = &sp; * Step 5 : Define a Triple pointer .. code-block:: c int ***tp = &dp; OR .. code-block:: c int ***tp; tp = &dp; * Step 6 : Access User data using single pointer variable ``sp`` .. code-block:: c printf("sp[3] = %c\n", sp[3]); * Step 7 : Access User data using double pointer variable ``dp`` .. code-block:: c printf("(*dp)[3] = %c\n", (*dp)[3]); * Step 8 : Access User data using triple pointer variable ``tp`` .. code-block:: c printf("(**tp)[3] = %c\n", (**tp)[3]); * Step 9 : Free memory after usage .. code-block:: c free(sp); OR .. code-block:: c free(*dp); OR .. code-block:: c free(**tp); * See full program below .. code-block:: c #include #include #include int main(void) { int *sp; sp = malloc(5 * sizeof(int)); sp[0] = 100; sp[1] = 200; sp[2] = 300; sp[3] = 400; sp[4] = 500; int **dp; dp = &sp; int ***tp; tp = &dp; //Access individual integer using "sp" printf("sp[3] = %d\n", sp[3]); //Access individual integer using "dp" printf("(*dp)[3] = %d\n", (*dp)[3]); //Access individual integer using "tp" printf("(**tp)[3] = %d\n", (**tp)[3]); // Access user data (in this case array of integers) using single pointer variable ``sp`` for (int i = 0 ; i < 5; i++) { printf("sp[%d] = %d\n", i, sp[i]); } // Access user data (in this case array of integers) using double pointer variable ``dp`` for (int i = 0 ; i < 5; i++) { printf("(*dp)[%d] = %d\n", i, (*dp)[i]); } // Access user data (in this case array of integers) using double pointer variable ``tp`` for (int i = 0 ; i < 5; i++) { printf("(**tp)[%d] = %d\n", i, (**tp)[i]); } free(sp); return 0; } * Output is as below .. code-block:: c sp[3] = 400 (*dp)[3] = 400 (**tp)[3] = 400 sp[0] = 100 sp[1] = 200 sp[2] = 300 sp[3] = 400 sp[4] = 500 (*dp)[0] = 100 (*dp)[1] = 200 (*dp)[2] = 300 (*dp)[3] = 400 (*dp)[4] = 500 (**tp)[0] = 100 (**tp)[1] = 200 (**tp)[2] = 300 (**tp)[3] = 400 (**tp)[4] = 500 .. _basic_ptr_int_tp_sp_ex4: .. tab-set:: .. tab-item:: 1 Triple Pointer, 1 Double Pointer : With two heap allocations : Create 1x1 array * Step 1 : Define a double pointer .. code-block:: c int **dp; * Step 2 : Allocate memory to a double pointer .. code-block:: c dp = malloc(sizeof(int *)); * Step 3 : Allocate memory to a single pointer .. code-block:: c *dp = malloc(sizeof(int)); * Step 4 : Store user data .. code-block:: c **dp = 65; * Step 5 : Define a Triple pointer .. code-block:: c int ***tp = &dp; OR .. code-block:: c int ***tp; tp = &dp; * Step 6 : Read user data using ``dp`` .. code-block:: c printf("**dp = %d\n", **dp); * Step 7 : Read user data using ``tp`` .. code-block:: c printf("***tp = %d\n", ***tp); * Step 8 : Free memory in opposite flow of allocation .. code-block:: c free(*dp); free(dp); OR .. code-block:: c free(**tp); free(*tp); * See full program below .. code-block:: c #include #include #include int main(void) { int **dp; dp = malloc(sizeof(int *)); *dp = malloc(sizeof(int)); **dp = 65; int ***tp; tp = &dp; printf("**dp = %d\n", **dp); printf("***tp = %d\n", ***tp); free(*dp); // or free(**tp); free(dp); // or free(*tp); return 0; } * Output is as below .. code-block:: c **dp = 65 ***tp = 65 .. _basic_ptr_int_tp_sp_ex5: .. tab-set:: .. tab-item:: 1 Triple Pointer, 1 Double Pointer : With two heap allocations : Create 1x10 array * Step 1 : Define a double pointer .. code-block:: c int **dp; * Step 2 : Allocate memory to a double pointer .. code-block:: c dp = malloc(sizeof(int *)); * Step 3 : Allocate memory to a single pointer .. code-block:: c *dp = malloc(5 * sizeof(int)); * Step 4 : Copy User data to heap .. code-block:: c (*dp)[0] = 100; (*dp)[1] = 200; (*dp)[2] = 300; (*dp)[3] = 400; (*dp)[4] = 500; * Step 5 : Define a Triple pointer .. code-block:: c int ***tp = &dp; OR .. code-block:: c int ***tp; tp = &dp; * Step 6 : Read user data from heap using ``dp`` .. code-block:: c for (int i = 0; i < 5; i++) { printf("(*dp)[%d] = %d\n", i, (*dp)[i]); } * Step 7 : Read user data from heap using ``tp`` .. code-block:: c for (int i = 0; i < 5; i++) { printf("(**tp)[%d] = %d\n", i, (**tp)[i]); } * Step 6 : Free memory in opposite flow of allocation .. code-block:: c free(*dp); free(dp); OR .. code-block:: c free(**tp); free(*tp); * See full program below .. code-block:: c #include #include #include int main(void) { int **dp; dp = malloc(sizeof(int *)); *dp = malloc(5 * sizeof(int)); memset(*dp, 0, 5 * sizeof(int)); (*dp)[0] = 100; (*dp)[1] = 200; (*dp)[2] = 300; (*dp)[3] = 400; (*dp)[4] = 500; int ***tp; tp = &dp; for (int i = 0; i < 5; i++) { printf("(*dp)[%d] = %d\n", i, (*dp)[i]); } for (int i = 0; i < 5; i++) { printf("(**tp)[%d] = %d\n", i, (**tp)[i]); } free(*dp); // or free(**tp); free(dp); // or free(*tp); return 0; } * Output is as below .. code-block:: c (*dp)[0] = 100 (*dp)[1] = 200 (*dp)[2] = 300 (*dp)[3] = 400 (*dp)[4] = 500 (**tp)[0] = 100 (**tp)[1] = 200 (**tp)[2] = 300 (**tp)[3] = 400 (**tp)[4] = 500 .. _basic_ptr_int_tp_sp_ex6: .. tab-set:: .. tab-item:: 1 Triple Pointer, 1 Double Pointer : Double Pointer Pointing to array of single pointers : Static * Step 1 : Define 3 Single dimension integer arrays .. code-block:: c int arr0[5] = {1, 2, 3, 4, 5}; int arr1[5] = {10, 20, 30, 40, 50}; int arr2[5] = {100, 200, 300, 400, 500}; * Step 2 : Define array of single pointers .. code-block:: c int *sp_arr[] = {arr0, arr1, arr2}; * Step 3 : Define a double pointer .. code-block:: c int **dp; dp = sp_arr; * Step 4 : Use ``dp`` to change contents of single dimension arrays .. code-block:: c * Step 5 : Define a Triple pointer .. code-block:: c int ***tp = &dp; OR .. code-block:: c int ***tp; tp = &dp; * Step 6 : Use ``sp_arr`` to access contents of single dimension arrays .. code-block:: c sp_arr[0][2] = 9; // Same as arr0[2] sp_arr[1][2] = 99; // Same as arr1[2] sp_arr[2][2] = 999; // Same as arr2[2] for (int i = 0; i < 3; i++) { for (int j = 0; j < 5; j++) { printf("sp_arr[%d][%d] = %d\n", i, j, sp_arr[i][j]); } printf("\n"); } * Step 7 : Use ``dp`` to access contents of single dimension arrays .. code-block:: c dp[0][2] = 9; // Same as arr0[2] dp[1][2] = 99; // Same as arr1[2] dp[2][2] = 999; // Same as arr2[2] printf("------------ Access arrays using dp -----------\n"); for (int i = 0; i < 3; i++) { for (int j = 0; j < 5; j++) { printf("dp[%d][%d] = %d\n", i, j, dp[i][j]); } printf("\n"); } * Step 8 : Use ``tp`` to access contents of single dimension arrays .. code-block:: c (*tp)[0][2] = 9; // Same as arr0[2] (*tp)[1][2] = 99; // Same as arr1[2] (*tp)[2][2] = 999; // Same as arr2[2] for (int i = 0; i < 3; i++) { for (int j = 0; j < 5; j++) { printf("(*tp)[%d][%d] = %d\n", i, j, (*tp)[i][j]); } printf("\n"); } * See full program below .. code-block:: c #include #include #include int main(void) { int arr0[5] = {1, 2, 3, 4, 5}; int arr1[5] = {10, 20, 30, 40, 50}; int arr2[5] = {100, 200, 300, 400, 500}; int *sp_arr[] = {arr0, arr1, arr2}; // Use ``sp_arr`` to change contents of single dimension arrays sp_arr[0][2] = 9; // Same as arr0[2] sp_arr[1][2] = 99; // Same as arr1[2] sp_arr[2][2] = 999; // Same as arr2[2] // Use ``sp_arr`` to access contents of single dimension arrays printf("------------ Access arrays using sp_arr -----------\n"); for (int i = 0; i < 3; i++) { for (int j = 0; j < 5; j++) { printf("sp_arr[%d][%d] = %d\n", i, j, sp_arr[i][j]); } printf("\n"); } int **dp; dp = sp_arr; // Use ``dp`` to change contents of single dimension arrays dp[0][2] = 9; // Same as arr0[2] dp[1][2] = 99; // Same as arr1[2] dp[2][2] = 999; // Same as arr2[2] // Use ``dp`` to access contents of single dimension arrays printf("------------ Access arrays using dp -----------\n"); for (int i = 0; i < 3; i++) { for (int j = 0; j < 5; j++) { printf("dp[%d][%d] = %d\n", i, j, dp[i][j]); } printf("\n"); } int ***tp; tp = &dp; // Use ``tp`` to change contents of single dimension arrays (*tp)[0][2] = 9; // Same as arr0[2] (*tp)[1][2] = 99; // Same as arr1[2] (*tp)[2][2] = 999; // Same as arr2[2] // Use ``tp`` to access contents of single dimension arrays printf("------------ Access arrays using tp -----------\n"); for (int i = 0; i < 3; i++) { for (int j = 0; j < 5; j++) { printf("(*tp)[%d][%d] = %d\n", i, j, (*tp)[i][j]); } printf("\n"); } return 0; } * Output is as below .. code-block:: c ------------ Access arrays using sp_arr ----------- sp_arr[0][0] = 1 sp_arr[0][1] = 2 sp_arr[0][2] = 9 sp_arr[0][3] = 4 sp_arr[0][4] = 5 sp_arr[1][0] = 10 sp_arr[1][1] = 20 sp_arr[1][2] = 99 sp_arr[1][3] = 40 sp_arr[1][4] = 50 sp_arr[2][0] = 100 sp_arr[2][1] = 200 sp_arr[2][2] = 999 sp_arr[2][3] = 400 sp_arr[2][4] = 500 ------------ Access arrays using dp ----------- dp[0][0] = 1 dp[0][1] = 2 dp[0][2] = 9 dp[0][3] = 4 dp[0][4] = 5 dp[1][0] = 10 dp[1][1] = 20 dp[1][2] = 99 dp[1][3] = 40 dp[1][4] = 50 dp[2][0] = 100 dp[2][1] = 200 dp[2][2] = 999 dp[2][3] = 400 dp[2][4] = 500 ------------ Access arrays using tp ----------- (*tp)[0][0] = 1 (*tp)[0][1] = 2 (*tp)[0][2] = 9 (*tp)[0][3] = 4 (*tp)[0][4] = 5 (*tp)[1][0] = 10 (*tp)[1][1] = 20 (*tp)[1][2] = 99 (*tp)[1][3] = 40 (*tp)[1][4] = 50 (*tp)[2][0] = 100 (*tp)[2][1] = 200 (*tp)[2][2] = 999 (*tp)[2][3] = 400 (*tp)[2][4] = 500 .. _basic_ptr_int_tp_sp_ex7: .. tab-set:: .. tab-item:: 1 Triple Pointer, 1 Double Pointer : Pointing to array of single pointers : Dynamic * Step 1 : Define a double pointer .. code-block:: c int **dp; * Step 2 : Allocate heap memory : Create 2 single pointers ``dp[0]``, ``dp[1]`` .. code-block:: c dp = malloc(2 * sizeof(int *)); * Step 3 : Allocate heap memory : Create 2 single dimension integer arrays of size 3 integers each .. code-block:: c dp[0] = malloc(3 * sizeof(int)); dp[1] = malloc(3 * sizeof(int)); * Step 4 : Store user data .. code-block:: c dp[0][0] = 1; dp[0][1] = 2; dp[0][2] = 3; dp[1][0] = 10; dp[1][1] = 20; dp[1][2] = 30; * Step 5 : Define a Triple pointer .. code-block:: c int ***tp = &dp; OR .. code-block:: c int ***tp; tp = &dp; * Step 6 : Access user data using ``dp`` .. code-block:: c for (int i = 0 ; i < 2; i++) { for (int j = 0; j < 3; j++) { printf("dp[%d][%d] = %d\n", i, j, dp[i][j]); } } * Step 7 : Access user data using ``tp`` .. code-block:: c for (int i = 0 ; i < 2; i++) { for (int j = 0; j < 3; j++) { printf("(*tp)[%d][%d] = %d\n", i, j, (*tp)[i][j]); } } * Step 6 : Free 2 integer arrays .. code-block:: c free(dp[0]); free(dp[1]); OR .. code-block:: c free((*tp)[0]); free((*tp)[1]); * Step 7 : Free 2 single pointers .. code-block:: c free(dp); * See full program below .. code-block:: c #include #include #include int main(void) { int **dp; dp = malloc(2 * sizeof(int *)); dp[0] = malloc(3 * sizeof(int)); dp[1] = malloc(3 * sizeof(int)); // Store user data using ``dp`` dp[0][0] = 1; dp[0][1] = 2; dp[0][2] = 3; dp[1][0] = 10; dp[1][1] = 20; dp[1][2] = 30; // Access user data using ``dp`` for (int i = 0 ; i < 2; i++) { for (int j = 0; j < 3; j++) { printf("dp[%d][%d] = %d\n", i, j, dp[i][j]); } } int ***tp; tp = &dp; // Access user data using ``tp`` for (int i = 0 ; i < 2; i++) { for (int j = 0; j < 3; j++) { printf("(*tp)[%d][%d] = %d\n", i, j, (*tp)[i][j]); } } free(dp[0]); free(dp[1]); free(dp); return 0; } * Output as is below .. code-block:: c dp[0][0] = 1 dp[0][1] = 2 dp[0][2] = 3 dp[1][0] = 10 dp[1][1] = 20 dp[1][2] = 30 (*tp)[0][0] = 1 (*tp)[0][1] = 2 (*tp)[0][2] = 3 (*tp)[1][0] = 10 (*tp)[1][1] = 20 (*tp)[1][2] = 30 .. card:: See Also * Current Module * :doc:`../basic_ptr` * Previous Module * :doc:`../../variable_and_ptr/variable_and_ptr` * Next Module * :doc:`../../array_n_ptrs/array_n_ptrs` * Other Modules * :doc:`../../malloc_ptr/malloc_ptr` * :doc:`../../typecasting_n_ptr/typecasting_n_ptr` * :doc:`../../funcs_n_ptrs/funcs_n_ptrs` * :doc:`../../memcpy_ptr/memcpy_ptr` * :doc:`../../const_ptr/const_ptr` * :doc:`../../void_ptr/void_ptr` * :doc:`../../array_of_ptr/array_of_ptr` * :doc:`../../ptr_to_array/ptr_to_array` * :doc:`../../function_ptr/function_ptr` * :doc:`../../pre_incr_ptr/pre_incr_ptr` * :doc:`../../post_incr_ptr/post_incr_ptr` * :doc:`../../pre_decr_ptr/pre_decr_ptr` * :doc:`../../post_decr_ptr/post_decr_ptr`