Basics of Structure 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 : Pass by Reference ` .. _basic_ptr_struct_dp_sp_ex1: .. tab-set:: .. tab-item:: 1 Double Pointer, 1 Single Pointer : Simple variables * Step 1 : Define a structure .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC x = { .a = 1, .b = 2, .c = 3 }; * Step 2 : Define a Single Pointer .. code-block:: c struct ABC *sp = &x; OR .. code-block:: c struct ABC *sp; sp = &x; * Step 3 : Define a Double Pointer .. code-block:: c struct ABC **dp = &sp; OR .. code-block:: c struct ABC **dp; dp = &sp; * Step 4 : Access user data (in this case structure) using single pointer ``sp`` .. code-block:: c printf("sp->a = %d\n", sp->a); printf("sp->b = %d\n", sp->b); printf("sp->c = %d\n", sp->c); * Step 5 : Access user data (in this case structure) using double pointer ``dp`` .. code-block:: c printf("(*dp)->a = %d\n", (*dp)->a); printf("(*dp)->b = %d\n", (*dp)->b); printf("(*dp)->c = %d\n", (*dp)->c); * See full program below .. code-block:: c #include struct ABC { int a; int b; int c; }; int main(void) { struct ABC x = { .a = 1, .b = 2, .c = 3 }; struct ABC *sp; sp = &x; struct ABC **dp; dp = &sp; printf("sp->a = %d\n", sp->a); printf("sp->b = %d\n", sp->b); printf("sp->c = %d\n", sp->c); printf("(*dp)->a = %d\n", (*dp)->a); printf("(*dp)->b = %d\n", (*dp)->b); printf("(*dp)->c = %d\n", (*dp)->c); return 0; } * Output is as below .. code-block:: c sp->a = 1 sp->b = 2 sp->c = 3 (*dp)->a = 1 (*dp)->b = 2 (*dp)->c = 3 .. _basic_ptr_struct_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 structures .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC arr[3] = { { .a = 1, .b = 2, .c = 3 }, { .a = 10, .b = 20, .c = 30 }, { .a = 100, .b = 200, .c = 300 }, }; * Step 2 : Define a single pointer .. code-block:: c struct ABC *sp = arr; OR .. code-block:: c struct ABC *sp; sp = arr; OR .. code-block:: c struct ABC *sp; sp = &arr[0]; * Step 3 : Define a double pointer .. code-block:: c struct ABC **dp = &sp; OR .. code-block:: c struct ABC **dp; dp = &sp; * Step 4 : Access user data (in this case array of structures) using single pointer variable ``arr`` .. code-block:: c for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++) { printf("arr[%d].a = %d\n", i, arr[i].a); printf("arr[%d].b = %d\n", i, arr[i].b); printf("arr[%d].c = %d\n", i, arr[i].c); } * Step 5 : Access user data (in this case array of structures) using single pointer variable ``sp`` .. code-block:: c for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++) { printf("sp[%d].a = %d\n", i, sp[i].a); printf("sp[%d].b = %d\n", i, sp[i].b); printf("sp[%d].c = %d\n", i, sp[i].c); } * Step 6 : Access user data (in this case array of structures) using double pointer variable ``dp`` .. code-block:: c for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++) { printf("(*dp)[%d].a = %d\n", i, (*dp)[i].a); printf("(*dp)[%d].b = %d\n", i, (*dp)[i].b); printf("(*dp)[%d].c = %d\n", i, (*dp)[i].c); } .. 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 struct ABC { int a; int b; int c; }; int main(void) { struct ABC arr[3] = { { .a = 1, .b = 2, .c = 3 }, { .a = 10, .b = 20, .c = 30 }, { .a = 100, .b = 200, .c = 300 }, }; struct ABC *sp; sp = arr; struct ABC **dp; dp = &sp; // Access user data (in this case array of structures) using single pointer variable ``arr`` for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++) { printf("arr[%d].a = %d\n", i, arr[i].a); printf("arr[%d].b = %d\n", i, arr[i].b); printf("arr[%d].c = %d\n", i, arr[i].c); } // Access user data (in this case array of structures) using single pointer variable ``sp`` for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++) { printf("sp[%d].a = %d\n", i, sp[i].a); printf("sp[%d].b = %d\n", i, sp[i].b); printf("sp[%d].c = %d\n", i, sp[i].c); } // Access user data (in this case array of structures) using double pointer variable ``dp`` for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++) { printf("(*dp)[%d].a = %d\n", i, (*dp)[i].a); printf("(*dp)[%d].b = %d\n", i, (*dp)[i].b); printf("(*dp)[%d].c = %d\n", i, (*dp)[i].c); } return 0; } * Output is as below .. code-block:: c arr[0].a = 1 arr[0].b = 2 arr[0].c = 3 arr[1].a = 10 arr[1].b = 20 arr[1].c = 30 arr[2].a = 100 arr[2].b = 200 arr[2].c = 300 sp[0].a = 1 sp[0].b = 2 sp[0].c = 3 sp[1].a = 10 sp[1].b = 20 sp[1].c = 30 sp[2].a = 100 sp[2].b = 200 sp[2].c = 300 (*dp)[0].a = 1 (*dp)[0].b = 2 (*dp)[0].c = 3 (*dp)[1].a = 10 (*dp)[1].b = 20 (*dp)[1].c = 30 (*dp)[2].a = 100 (*dp)[2].b = 200 (*dp)[2].c = 300 .. _basic_ptr_struct_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 struct ABC { int a; int b; int c; }; struct ABC *sp; * Step 2 : Allocate heap memory to single pointer .. code-block:: c sp = malloc(3 * sizeof(struct ABC)); * Step 3 : Copy User data to heap memory .. code-block:: c sp[0].a = 1; sp[0].b = 2; sp[0].c = 3; sp[1].a = 4; sp[1].b = 5; sp[1].c = 6; sp[2].a = 7; sp[2].b = 8; sp[2].c = 9; * Step 4 : Define a double pointer .. code-block:: c struct ABC **dp; dp = &sp; * Step 5 : Access User data using single pointer variable ``sp`` .. code-block:: c for (int i = 0 ; i < 3; i++) { printf("sp[%d].a = %d\n", i, sp[i].a); printf("sp[%d].b = %d\n", i, sp[i].b); printf("sp[%d].c = %d\n", i, sp[i].c); } * Step 6 : Access User data using double pointer variable ``dp`` .. code-block:: c for (int i = 0 ; i < 3; i++) { printf("(*dp)[%d].a = %d\n", i, (*dp)[i].a); printf("(*dp)[%d].b = %d\n", i, (*dp)[i].b); printf("(*dp)[%d].c = %d\n", i, (*dp)[i].c); } * Step 7 : Free heap memory after use .. code-block:: c free(sp); OR .. code-block:: c free(*dp); * See full program below .. code-block:: c #include #include #include struct ABC { int a; int b; int c; }; int main(void) { struct ABC *sp; sp = malloc(3 * sizeof(struct ABC)); memset(sp, 0, 3 * sizeof(struct ABC)); sp[0].a = 1; sp[0].b = 2; sp[0].c = 3; sp[1].a = 4; sp[1].b = 5; sp[1].c = 6; sp[2].a = 7; sp[2].b = 8; sp[2].c = 9; struct ABC **dp; dp = &sp; // Access user data (in this case array of structures) using single pointer variable ``sp`` for (int i = 0 ; i < 3; i++) { printf("sp[%d].a = %d\n", i, sp[i].a); printf("sp[%d].b = %d\n", i, sp[i].b); printf("sp[%d].c = %d\n", i, sp[i].c); } // Access user data (in this case array of structures) using double pointer variable ``dp`` for (int i = 0 ; i < 3; i++) { printf("(*dp)[%d].a = %d\n", i, (*dp)[i].a); printf("(*dp)[%d].b = %d\n", i, (*dp)[i].b); printf("(*dp)[%d].c = %d\n", i, (*dp)[i].c); } free(sp); return 0; } * Output is as below .. code-block:: c sp[0].a = 1 sp[0].b = 2 sp[0].c = 3 sp[1].a = 4 sp[1].b = 5 sp[1].c = 6 sp[2].a = 7 sp[2].b = 8 sp[2].c = 9 (*dp)[0].a = 1 (*dp)[0].b = 2 (*dp)[0].c = 3 (*dp)[1].a = 4 (*dp)[1].b = 5 (*dp)[1].c = 6 (*dp)[2].a = 7 (*dp)[2].b = 8 (*dp)[2].c = 9 .. _basic_ptr_struct_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 struct ABC { int a; int b; int c; }; struct ABC **dp; * Step 2 : Allocate memory to a double pointer .. code-block:: c dp = malloc(sizeof(struct ABC *)); * Step 3 : Allocate memory to a single pointer .. code-block:: c *dp = malloc(sizeof(struct ABC)); * Step 4 : Store user data .. code-block:: c (**dp).a = 1; (**dp).b = 2; (**dp).c = 3; * Step 5 : Read user data .. code-block:: c printf("(**dp).a = %d\n", (**dp).a); printf("(**dp).b = %d\n", (**dp).b); printf("(**dp).c = %d\n", (**dp).c); * 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 struct ABC { int a; int b; int c; }; int main(void) { struct ABC **dp; dp = malloc(sizeof(struct ABC *)); *dp = malloc(sizeof(struct ABC)); (**dp).a = 1; (**dp).b = 2; (**dp).c = 3; printf("(**dp).a = %d\n", (**dp).a); printf("(**dp).b = %d\n", (**dp).b); printf("(**dp).c = %d\n", (**dp).c); free(*dp); free(dp); return 0; } * Output is as below .. code-block:: c (**dp).a = 1 (**dp).b = 2 (**dp).c = 3 .. _basic_ptr_struct_dp_sp_ex5: .. tab-set:: .. tab-item:: 1 Double Pointer : With two heap allocations : Create 1x3 array * Step 1 : Define a double pointer .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC **dp; * Step 2 : Allocate memory to a double pointer .. code-block:: c dp = malloc(sizeof(struct ABC *)); * Step 3 : Allocate memory to a single pointer .. code-block:: c *dp = malloc(3 * sizeof(struct ABC)); * Step 4 : Copy User data to heap .. code-block:: c (*dp)[0].a = 1; (*dp)[0].b = 2; (*dp)[0].c = 3; (*dp)[1].a = 4; (*dp)[1].b = 5; (*dp)[1].c = 6; (*dp)[2].a = 7; (*dp)[2].b = 8; (*dp)[2].c = 9; * Step 5 : Read user data from heap .. code-block:: c for (int i = 0; i < 3; i++) { printf("(*dp)[%d].a = %d\n", i, (*dp)[i].a); printf("(*dp)[%d].b = %d\n", i, (*dp)[i].b); printf("(*dp)[%d].c = %d\n", i, (*dp)[i].c); } * 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 struct ABC { int a; int b; int c; }; int main(void) { struct ABC **dp; dp = malloc(sizeof(struct ABC *)); *dp = malloc(3 * sizeof(struct ABC)); memset(*dp, 0, 3 * sizeof(struct ABC) ); (*dp)[0].a = 1; (*dp)[0].b = 2; (*dp)[0].c = 3; (*dp)[1].a = 4; (*dp)[1].b = 5; (*dp)[1].c = 6; (*dp)[2].a = 7; (*dp)[2].b = 8; (*dp)[2].c = 9; for (int i = 0; i < 3; i++) { printf("(*dp)[%d].a = %d\n", i, (*dp)[i].a); printf("(*dp)[%d].b = %d\n", i, (*dp)[i].b); printf("(*dp)[%d].c = %d\n", i, (*dp)[i].c); } free(*dp); free(dp); return 0; } * See full program below .. code-block:: c (*dp)[0].a = 1 (*dp)[0].b = 2 (*dp)[0].c = 3 (*dp)[1].a = 4 (*dp)[1].b = 5 (*dp)[1].c = 6 (*dp)[2].a = 7 (*dp)[2].b = 8 (*dp)[2].c = 9 .. _basic_ptr_struct_dp_sp_ex9: .. tab-set:: .. tab-item:: 1 Double Pointer : Pass by Reference * Step 1 : Define a double pointer .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC **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(struct ABC ***dp_r) { *dp_r = malloc(2 * sizeof(struct ABC *)); (*dp_r)[0] = malloc(3 * sizeof(struct ABC)); (*dp_r)[1] = malloc(3 * sizeof(struct ABC)); } * Step 4 : Use single pointers dp[0], dp[1] in caller to store user data .. code-block:: c dp[0][0].a = 1; dp[0][0].b = 2; dp[0][0].c = 3; dp[0][1].a = 4; dp[0][1].b = 5; dp[0][1].c = 6; dp[0][2].a = 7; dp[0][2].b = 8; dp[0][2].c = 9; dp[1][0].a = 10; dp[1][0].b = 11; dp[1][0].c = 12; dp[1][1].a = 13; dp[1][1].b = 14; dp[1][1].c = 15; dp[1][2].a = 16; dp[1][2].b = 17; dp[1][2].c = 18; * 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].a = %d\n", i, j, dp[i][j].a); printf("dp[%d][%d].b = %d\n", i, j, dp[i][j].b); printf("dp[%d][%d].c = %d\n", i, j, dp[i][j].c); } printf("\n"); } * Step 6 : Free 2 arrays of structures after use .. code-block:: c free(dp[0]); free(dp[1]); * Step 7 : Free 2 Single pointers after use .. code-block:: c free(dp); * See full program below .. code-block:: c #include #include #include struct ABC { int a; int b; int c; }; void fun(struct ABC ***dp_r) { *dp_r = malloc(2 * sizeof(struct ABC *)); (*dp_r)[0] = malloc(3 * sizeof(struct ABC)); (*dp_r)[1] = malloc(3 * sizeof(struct ABC)); } int main(void) { struct ABC **dp; fun(&dp); dp[0][0].a = 1; dp[0][0].b = 2; dp[0][0].c = 3; dp[0][1].a = 4; dp[0][1].b = 5; dp[0][1].c = 6; dp[0][2].a = 7; dp[0][2].b = 8; dp[0][2].c = 9; dp[1][0].a = 10; dp[1][0].b = 11; dp[1][0].c = 12; dp[1][1].a = 13; dp[1][1].b = 14; dp[1][1].c = 15; dp[1][2].a = 16; dp[1][2].b = 17; dp[1][2].c = 18; for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { printf("dp[%d][%d].a = %d\n", i, j, dp[i][j].a); printf("dp[%d][%d].b = %d\n", i, j, dp[i][j].b); printf("dp[%d][%d].c = %d\n", i, j, dp[i][j].c); } printf("\n"); } free(dp[0]); free(dp[1]); free(dp); return 0; } * See full program below .. code-block:: c dp[0][0].a = 1 dp[0][0].b = 2 dp[0][0].c = 3 dp[0][1].a = 4 dp[0][1].b = 5 dp[0][1].c = 6 dp[0][2].a = 7 dp[0][2].b = 8 dp[0][2].c = 9 dp[1][0].a = 10 dp[1][0].b = 11 dp[1][0].c = 12 dp[1][1].a = 13 dp[1][1].b = 14 dp[1][1].c = 15 dp[1][2].a = 16 dp[1][2].b = 17 dp[1][2].c = 18 .. 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`