Basics of Integer Double 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 Double Pointers ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Basics of Double Pointers * :ref:`1 Double Pointer, 1 Single Pointer : Simple variables ` * :ref:`1 Double Pointer, 1 Single Pointer : With Single pointer pointing to arrays ` * :ref:`1 Double Pointer, 1 Single Pointer : With Single pointer heap allocation ` * :ref:`1 Double Pointer : With two heap allocations : Create 1x1 array ` * :ref:`1 Double Pointer : With two heap allocations : Create 1x10 array ` * :ref:`1 Double Pointer : Pointing to array of single pointers : Static ` * :ref:`1 Double Pointer : Pointing to array of single pointers : Dynamic ` * :ref:`1 Double Pointer : Pass by Reference ` .. _basic_ptr_int_dp_sp_ex1: .. tab-set:: .. tab-item:: 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 : Access user data (in this case integer) using single pointer .. code-block:: c printf("c = %d\n", *sp); * Step 5 : Access user data (in this case integer) using double pointer .. code-block:: c printf("c = %d\n", **dp); * Step 6 : Use ``*dp`` to point to new user data (in this case variable ``d``) .. code-block:: c *dp = &d; .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Remember below equations * dp = &sp * \*dp = sp * \*dp = &c * Hence changing ``*dp`` changes ``sp`` as well * Step 7 : Now user data can be accessed using \*sp, \*\*dp which prints value of integer ``d`` .. code-block:: c printf("d = %d\n", d); printf("d = %d\n", *sp); printf("d = %d\n", **dp); * See full program below .. code-block:: c #include int main(void) { int c = 65; int *sp = &c; int **dp = &sp; printf("c = %d\n", c); printf("*sp = %d\n", *sp); printf("**dp = %d\n", **dp); int d = 100; *dp = &d; printf("d = %d\n", d); printf("*sp = %d\n", *sp); printf("**dp = %d\n", **dp); return 0; } * Output is as below .. code-block:: c c = 65 *sp = 65 **dp = 65 d = 100 *sp = 100 **dp = 100 .. _basic_ptr_int_dp_sp_ex2: .. tab-set:: .. tab-item:: 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 : 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]); } .. 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; * 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; // Access user data (in this case array of integers) using single pointer variable ``arr`` for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++) { printf("arr[%d] = %d\n", i, arr[i]); } // Access user data (in this case array of integers) using single pointer variable ``sp`` for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); 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 < sizeof(arr)/sizeof(arr[0]); i++) { printf("(*dp)[%d] = %d\n", i, (*dp)[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 .. _basic_ptr_int_dp_sp_ex3: .. tab-set:: .. tab-item:: 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 : Access User data using single pointer variable ``sp`` .. code-block:: c printf("sp[3] = %d\n", sp[3]); * Step 6 : Access User data using double pointer variable ``dp`` .. code-block:: c printf("(*dp)[3] = %d\n", (*dp)[3]); * See full program below .. code-block:: c #include #include #include int main(void) { int *sp; sp = malloc(5 * sizeof(int)); memset(sp, 0, 5 * sizeof(int)); sp[0] = 100; sp[1] = 200; sp[2] = 300; sp[3] = 400; sp[4] = 500; int **dp; dp = &sp; //Access individual integer printf("sp[3] = %d\n", sp[3]); printf("(*dp)[3] = %d\n", (*dp)[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]); } free(sp); return 0; } * Output is as below .. code-block:: c sp[3] = 400 (*dp)[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 .. _basic_ptr_int_dp_sp_ex4: .. tab-set:: .. tab-item:: 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 : Read user data .. code-block:: c printf("**dp = %d\n", **dp); * Step 6 : Free memory in opposite flow of allocation .. code-block:: c free(*dp); free(dp); * 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; printf("**dp = %d\n", **dp); free(*dp); free(dp); return 0; } * Output is as below .. code-block:: c **dp = 65 .. _basic_ptr_int_dp_sp_ex5: .. tab-set:: .. tab-item:: 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 : Read user data from heap .. code-block:: c for (int i = 0; i < 5; i++) { printf("(*dp)[i] = %d\n", (*dp)[i]); } * Step 6 : Free memory in opposite flow of allocation .. code-block:: c free(*dp); free(dp); * 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; for (int i = 0; i < 5; i++) { printf("(*dp)[%d] = %d\n", i, (*dp)[i]); } free(*dp); free(dp); return 0; } * See full program below .. code-block:: c (*dp)[0] = 100 (*dp)[1] = 200 (*dp)[2] = 300 (*dp)[3] = 400 (*dp)[4] = 500 .. _basic_ptr_int_dp_sp_ex6: .. tab-set:: .. tab-item:: 1 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 : Use ``sp_arr`` to change 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] * Step 4 : Use ``sp_arr`` to access contents of single dimension arrays .. code-block:: c 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 5 : Define a double pointer .. code-block:: c int **dp; dp = sp_arr; * Step 6 : Use ``dp`` to change 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] * Step 7 : Use ``dp`` to access contents of single dimension arrays .. code-block:: c 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"); } * 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"); } // Define a double pointer 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"); } return 0; } * See full program 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 .. _basic_ptr_int_dp_sp_ex7: .. tab-set:: .. tab-item:: 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 3 single dimension integer arrays of size 32 integers each .. code-block:: c dp[0] = malloc(3 * sizeof(int)); dp[1] = malloc(3 * sizeof(int)); * Step 4 : Store user data using ``dp`` .. 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 : 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 6 : Free 3 integer arrays .. code-block:: c free(dp[0]); free(dp[1]); * Step 7 : Free 3 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]); } } free(dp[0]); free(dp[1]); free(dp); return 0; } * Output is as 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 .. _basic_ptr_int_dp_sp_ex9: .. tab-set:: .. tab-item:: 1 Double Pointer : Pass by Reference * Step 1 : Define a double pointer .. code-block:: c int **dp; * Step 2 : Pass double pointer by reference .. code-block:: c fun(&dp); * Step 3 : Allocate memory inside function ``fun`` .. code-block:: c void fun(int ***dp_r) { *dp_r = malloc(2 * sizeof(int *)); (*dp_r)[0] = malloc(3 * sizeof(int)); (*dp_r)[1] = malloc(3 * sizeof(int)); } * Step 4 : Use single pointers dp[0], dp[1] in caller to 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 : Use single pointers dp[0], dp[1] in caller to access user data .. 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 6 : Free 3 arrays of integers after use .. code-block:: c free(dp[0]); free(dp[1]); * Step 7 : Free 3 Single pointers after use .. code-block:: c free(dp); * See full program below .. code-block:: c #include #include #include void fun(int ***dp_r) { *dp_r = malloc(2 * sizeof(int *)); (*dp_r)[0] = malloc(3 * sizeof(int)); (*dp_r)[1] = malloc(3 * sizeof(int)); } int main(void) { int **dp; fun(&dp); // 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]); } } free(dp[0]); free(dp[1]); free(dp); return 0; } * See full program 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 .. 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`