Malloc struct Double pointer ============================== * In this section, you are going to learn .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to allocate memory using malloc ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to allocate memory using calloc ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to allocate memory using realloc ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Topics in this section, * :ref:`Create a 1,1 array ` * :ref:`Create a 1,10 array ` * :ref:`Create a 10,1 array ` * :ref:`Create a 10,10 array ` * :ref:`Pass Single pointer by reference and allocate memory inside function ` * :ref:`Pass Double pointer by reference and allocate memory inside function ` * Key point to remember * Double pointer points to array of single pointers * Single pointer points to array of structures .. tab-set:: .. tab-item:: Homogeneous Arrays : Where Every Row has equal number of blocks * Example is arr[2][3] * Where there are 2 rows and 3 columns * Now let us take a look at real time examples .. _struct_dp_1x1_array: .. tab-set:: .. tab-item:: Create a 1,1 array * Step 1 : Include stdlib.h .. code-block:: c #include * Step 2 : Define Double pointer .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC **ptr; * Step 3 : Create One single pointer .. code-block:: c ptr = malloc( sizeof(struct ABC *) ); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Allocates 8 Bytes of memory in heap .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * ``ptr`` points to array of single pointers * In this case, array has one single pointer .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * sizeof(ptr) is 8 Bytes * Step 4 : Create One single structure .. code-block:: c *ptr = malloc( sizeof(struct ABC) ); OR .. code-block:: c ptr[0] = malloc( sizeof(struct ABC) ); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Allocates 12 Bytes of memory in heap * Step 5 : Assign value to structure .. code-block:: c (*ptr)->a = 65; OR .. code-block:: c (*ptr)[0].a = 65; OR .. code-block:: c ptr[0][0].a = 65; * Step 6 : Print the value .. code-block:: c printf("(*ptr)->a = %d\n", (*ptr)->a); OR .. code-block:: c printf("(*ptr)[0].a = %d\n", (*ptr)[0].a); OR .. code-block:: c printf("ptr[0][0].a = %d\n", ptr[0][0].a); * Step 7 : Free after use .. code-block:: c free(*ptr); free(ptr); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Free in the opposite order of allocation * See the full program below .. code-block:: c :linenos: :emphasize-lines: 15, 18, 21, 24, 29, 32, 36, 37 #include // Step 1 : Include stdlib.h #include int main(void) { // Step 2 : Define Double pointer struct ABC { int a; int b; int c; }; struct ABC **ptr; // Step 3 : Create One single pointer ptr = malloc( sizeof(struct ABC *) ); // Step 4 : Create One single structure *ptr = malloc( sizeof(struct ABC) ); // Step 5 : Assign value to structure (*ptr)->a = 65; // Step 6 : Print the value printf("(*ptr)->a = %d\n", (*ptr)->a); (*ptr)[0].a = 66; printf("(*ptr)[0].a = %d\n", (*ptr)[0].a); ptr[0][0].a = 67; printf("ptr[0][0].a = %d\n", ptr[0][0].a); // Step 7 : Free after use free(*ptr); free(ptr); return 0; } .. tab-set:: .. tab-item:: Summary of 1,1 array =========================================== ============================================================= Statement Description =========================================== ============================================================= ptr = malloc( sizeof(struct ABC \*) ) * ``ptr`` points to array of single pointers \*ptr = malloc( sizeof(struct ABC) ) * ``*ptr`` points to array of structures sizeof(ptr) * 8 Bytes * Not fully dereferenced * Hence ``ptr`` is a pointer * sizeof(pointer) is 8 Bytes always sizeof(\*ptr) * 8 Bytes * Not fully dereferenced * Hence ``*ptr`` is a pointer * sizeof(pointer) is 8 Bytes always sizeof(\*\*ptr) * 12 Bytes * Fully dereferenced * Hence takes the size of actual type (\*ptr)->a * Method 1 : Access member (\*ptr)[0].a * Method 2 : Access member ptr[0][0].a * Method 3 : Access member =========================================== ============================================================= .. _struct_dp_1x10_array: .. tab-set:: .. tab-item:: Create a 1,10 array * Step 1 : Include stdlib.h .. code-block:: c #include * Step 2 : Define Double pointer .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC **ptr; * Step 3 : Create One single pointer .. code-block:: c ptr = malloc( sizeof(struct ABC *) ); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Allocates 8 Bytes of memory in heap .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * ``ptr`` points to array of single pointers * In this case, array has one single pointer .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * sizeof(ptr) is 8 Bytes * Step 4 : Create Ten Structure Objects from (\*ptr)[0] ... (\*ptr)[9] .. code-block:: c *ptr = malloc( 10 * sizeof(struct ABC) ); OR .. code-block:: c ptr[0] = malloc( 10 * sizeof(struct ABC) ); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Allocates 120 Bytes of memory in heap * Step 5 : Assign value to structure .. code-block:: c for (int i = 0; i < 10; i++) { (*ptr)[i].a = ++val; } OR .. code-block:: c for (int i = 0; i < 10; i++) { ptr[0][i].a = ++val; } OR .. code-block:: c for (int i = 0; i < 10; i++) { ( *( *( ptr ) + i ) ).a = ++val; } OR .. code-block:: c for (int i = 0; i < 10; i++) { (*ptr + i)->a = ++val; } * Step 6 : Print the value .. code-block:: c for (int i = 0; i < 10; i++) { printf("(*ptr)[%d].a = %d\n", i, (*ptr)[i].a); } OR .. code-block:: c for (int i = 0; i < 10; i++) { printf("ptr[0][%d].a = %d\n", i, ptr[0][i].a); } OR .. code-block:: c for (int i = 0; i < 10; i++) { printf("( *( *( ptr ) + %d ) ).a = %d\n", i, ( *( *( ptr ) + i ) ).a ); } OR .. code-block:: c for (int i = 0; i < 10; i++) { printf("(*ptr + %d)->a = %d\n", i, (*ptr + i)->a ); } * Step 7 : Free after use .. code-block:: c free(*ptr); free(ptr); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Free in the opposite order of allocation * See the full program below .. code-block:: c :linenos: :emphasize-lines: 15, 19, 22, 27, 33, 39, 45, 52, 58, 64, 70, 74, 75 #include // Step 1 : Include stdlib.h #include int main(void) { // Step 2 : Define Double pointer struct ABC { int a; int b; int c; }; struct ABC **ptr; int val = 0; // Step 3 : Create One single pointer ptr = malloc( sizeof(struct ABC *) ); // Step 4 : Create Ten Structure Objects from (*ptr)[0] ... (*ptr)[9] *ptr = malloc( 10 * sizeof(struct ABC) ); // Step 5.1 : Assign value to structure objects for (int i = 0; i < 10; i++) { (*ptr)[i].a = ++val; } // Step 6.1 : Print the value for (int i = 0; i < 10; i++) { printf("(*ptr)[%d].a = %d\n", i, (*ptr)[i].a); } // Step 5.2 : Assign value to structure objects for (int i = 0; i < 10; i++) { ptr[0][i].a = ++val; } // Step 6.2 : Print the value for (int i = 0; i < 10; i++) { printf("ptr[0][%d].a = %d\n", i, ptr[0][i].a); } // Step 5.3 : Assign value to structure objects for (int i = 0; i < 10; i++) { ( *( *( ptr ) + i ) ).a = ++val; } // Step 6.3 : Print the value for (int i = 0; i < 10; i++) { printf("( *( *( ptr ) + %d ) ).a = %d\n", i, ( *( *( ptr ) + i ) ).a ); } // Step 5.4 : Assign value to structure objects for (int i = 0; i < 10; i++) { (*ptr + i)->a = ++val; } // Step 6.4 : Print the value for (int i = 0; i < 10; i++) { printf("(*ptr + %d)->a = %d\n", i, (*ptr + i)->a ); } // Step 7 : Free after use free(*ptr); free(ptr); return 0; } .. tab-set:: .. tab-item:: Summary of 1,10 array =========================================== ============================================================= Statement Description =========================================== ============================================================= ptr = malloc( sizeof(struct ABC \*) ) * ``ptr`` points to array of single pointers \*ptr = malloc( 10 * sizeof(struct ABC) ) * ``*ptr`` points to array of 10 structures sizeof(ptr) * 8 Bytes * Not fully dereferenced * Hence ``ptr`` is a pointer * sizeof(pointer) is 8 Bytes always sizeof(\*ptr) * 8 Bytes * Not fully dereferenced * Hence ``*ptr`` is a pointer * sizeof(pointer) is 8 Bytes always sizeof(\*\*ptr) * 12 Bytes * Fully dereferenced * Hence takes the size of actual type ( \*ptr )[ i ].a * Method 1 : Access member ptr[ 0 ][ i ].a * Method 2 : Access member ( \*( \*( ptr ) + i ) ).a * Method 3 : Access member ( \*ptr + i )->a * Method 4 : Access member =========================================== ============================================================= .. _struct_dp_10x1_array: .. tab-set:: .. tab-item:: Create a 10,1 array * Step 1 : Include stdlib.h .. code-block:: c #include * Step 2 : Define Double pointer .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC **ptr; * Step 3 : Create Ten single pointers from ptr[0] to ptr[9] .. code-block:: c ptr = malloc( 10 * sizeof(struct ABC *) ); * Step 4 : Create One Structure Object from ptr[0][0] to ptr[9][0] .. code-block:: c for (int i = 0; i < 10; i++) { ptr[i] = malloc( sizeof(struct ABC) ); } * Step 5 : Assign value to structure objects .. code-block:: c for (int i = 0; i < 10; i++) { ptr[i][0].a = ++val; } OR .. code-block:: c for (int i = 0; i < 10; i++) { ptr[i]->a = ++val; } OR .. code-block:: c for (int i = 0; i < 10; i++) { (*(ptr + i))->a = ++val; } OR .. code-block:: c for (int i = 0; i < 10; i++) { ( *( *( ptr + i ) ) ).a = ++val; } * Step 6 : Print the value .. code-block:: c for (int i = 0; i < 10; i++) { printf("ptr[%d][0].a = %d\n", i, ptr[i][0].a); } OR .. code-block:: c for (int i = 0; i < 10; i++) { printf("ptr[%d]->a = %d\n", i, ptr[i]->a); } OR .. code-block:: c for (int i = 0; i < 10; i++) { printf("(*(ptr + %d))->a = %d\n", i, (*(ptr + i))->a); } OR .. code-block:: c for (int i = 0; i < 10; i++) { printf("( *( *( ptr + %d ) ) ).a = %d\n", i, ( *( *( ptr + i ) ) ).a ); } * Step 7 : Free after use .. code-block:: c for (int i = 0; i < 10; i++) { free(ptr[i]); } free(ptr); * See the full program below .. code-block:: c :linenos: :emphasize-lines: 15, 19, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 81 #include // Step 1 : Include stdlib.h #include int main(void) { // Step 2 : Define Double pointer struct ABC { int a; int b; int c; }; struct ABC **ptr; int val = 0; // Step 3 : Create Ten single pointers from ptr[0] to ptr[9] ptr = malloc( 10 * sizeof(struct ABC *) ); // Step 4 : Create One Structure Object from ptr[0][0] to ptr[9][0] for (int i = 0; i < 10; i++) { ptr[i] = malloc( sizeof(struct ABC) ); } // Step 5.1 : Assign value to structure objects for (int i = 0; i < 10; i++) { ptr[i][0].a = ++val; } // Step 6.1 : Print the value for (int i = 0; i < 10; i++) { printf("ptr[%d][0].a = %d\n", i, ptr[i][0].a); } // Step 5.2 : Assign value to structure objects for (int i = 0; i < 10; i++) { ptr[i]->a = ++val; } // Step 6.2 : Print the value for (int i = 0; i < 10; i++) { printf("ptr[%d]->a = %d\n", i, ptr[i]->a); } // Step 5.3 : Assign value to structure objects for (int i = 0; i < 10; i++) { (*(ptr + i))->a = ++val; } // Step 6.3 : Print the value for (int i = 0; i < 10; i++) { printf("(*(ptr + %d))->a = %d\n", i, (*(ptr + i))->a); } // Step 5.4 : Assign value to structure objects for (int i = 0; i < 10; i++) { ( *( *( ptr + i ) ) ).a = ++val; } // Step 6.4 : Print the value for (int i = 0; i < 10; i++) { printf("( *( *( ptr + %d ) ) ).a = %d\n", i, ( *( *( ptr + i ) ) ).a ); } // Step 7 : Free after use for (int i = 0; i < 10; i++) { free(ptr[i]); } free(ptr); return 0; } .. _struct_dp_10x10_array: .. tab-set:: .. tab-item:: Create a 10,10 array * Step 1 : Include stdlib.h .. code-block:: c #include * Step 2 : Define Double pointer .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC **ptr; * Step 3 : Create Ten single pointers from ptr[0] to ptr[9] .. code-block:: c ptr = malloc( 10 * sizeof(struct ABC *) ); * Step 4 : Create 100 Structure Objects from ptr[0][0] to ptr[9][9] .. code-block:: c for (int i = 0; i < 10; i++) { ptr[i] = malloc( 10 * sizeof(struct ABC) ); } * Step 5 : Assign value to structure objects .. code-block:: c for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { ptr[i][j].a = ++val; } } * Step 6 : Print the value .. code-block:: c for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { printf("ptr[%d][%d].a = %d\n", i, j, ptr[i][j].a); } } * Step 7 : Free after use .. code-block:: c for (int i = 0; i < 10; i++) { free(ptr[i]); } free(ptr); * See the full program below .. code-block:: c #include // Step 1 : Include stdlib.h #include int main(void) { // Step 2 : Define Double pointer struct ABC { int a; int b; int c; }; struct ABC **ptr; int val = 0; // Step 3 : Create Ten single pointers from ptr[0] to ptr[9] ptr = malloc( 10 * sizeof(struct ABC *) ); // Step 4 : Create 100 Structure Objects from ptr[0][0] to ptr[9][9] for (int i = 0; i < 10; i++) { ptr[i] = malloc( 10 * sizeof(struct ABC) ); } // Step 5 : Assign value to structure objects for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { ptr[i][j].a = ++val; } } // Step 6 : Print the value for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { printf("ptr[%d][%d].a = %d\n", i, j, ptr[i][j].a); } } // Step 7 : Free after use for (int i = 0; i < 10; i++) { free(ptr[i]); } free(ptr); return 0; } .. _struct_sp_passed_by_reference: .. tab-set:: .. tab-item:: Pass Single pointer by reference and allocate memory inside function * Step 1 : Include stdlib.h .. code-block:: c #include * Step 2 : Define an allocation function .. code-block:: c void get_memory(struct ABC **dp) { // *dp is equal to sp in caller *dp = malloc(10 * sizeof(struct ABC)); memset(*dp, 0, 10 * sizeof(struct ABC)); } * Step 3: Define a single pointer .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC *sp; * Step 4 : Pass single pointer ``sp`` by reference .. code-block:: c get_memory(&sp); * Step 5.1 : ``sp`` is now pointing to array of 10 structures. Access members and assign .. code-block:: c for (int i = 0; i < 10; i++) { sp[i].a = ++val; } OR .. code-block:: c for (int i = 0; i < 10; i++) { (sp + i)->a = ++val; } OR .. code-block:: c for (int i = 0; i < 10; i++) { (*(sp + i)).a = ++val; } * Step 5.2 : Print the values .. code-block:: c for (int i = 0; i < 10; i++) { printf("sp[%d].a = %d\n", i, sp[i].a); } OR .. code-block:: c for (int i = 0; i < 10; i++) { printf("(sp + %d)->a = %d\n", i, (sp + i)->a); } OR .. code-block:: c for (int i = 0; i < 10; i++) { printf("(*(sp + %d)).a = %d\n", i, (*(sp + i)).a); } * Step 6 : Free the memory .. code-block:: c free(sp); * See full program below .. code-block:: c :linenos: :emphasize-lines: 17, 29, 34, 45, 55, 64 #include #include // Step 1 : Include stdlib.h #include struct ABC { int a; int b; int c; }; // Step 2 : Define an allocation function void get_memory(struct ABC **dp) { // *dp is equal to sp in caller *dp = malloc(10 * sizeof(struct ABC)); memset(*dp, 0, 10 * sizeof(struct ABC)); } int main(void) { // Step 3: Define a single pointer struct ABC *sp; int val = 0; // Step 4 : Pass single pointer "sp" by reference get_memory(&sp); // Step 5.1 : "sp" is now pointing to array of 10 structures from sp[0] to sp[9] for (int i = 0; i < 10; i++) { sp[i].a = ++val; } // Step 5.2 : Print the values for (int i = 0; i < 10; i++) { printf("sp[%d].a = %d\n", i, sp[i].a); } for (int i = 0; i < 10; i++) { (sp + i)->a = ++val; } for (int i = 0; i < 10; i++) { printf("(sp + %d)->a = %d\n", i, (sp + i)->a); } for (int i = 0; i < 10; i++) { (*(sp + i)).a = ++val; } for (int i = 0; i < 10; i++) { printf("(*(sp + %d)).a = %d\n", i, (*(sp + i)).a); } // Step 6 : Free the memory free(sp); return 0; } .. _struct_dp_passed_by_reference: .. tab-set:: .. tab-item:: Pass Double pointer by reference and allocate memory inside function * Step 1 : Include stdlib.h .. code-block:: c #include * Step 2 : Define an allocation function .. code-block:: c void get_memory(struct ABC ***tp) { } * Step 2.1 : Create Ten Single Pointers from tp[0] ... tp[9] .. code-block:: c :emphasize-lines: 3 void get_memory(struct ABC ***tp) { *tp = malloc( 10 * sizeof(struct ABC *) ); } .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * ``tp`` is a triple pointer * ``*tp`` is a double pointer and will point to array of single pointers ! * Step 2.2 : Create Ten Characters in every Row .. code-block:: c :emphasize-lines: 5, 6, 7, 8 void get_memory(struct ***tp) { *tp = malloc( 10 * sizeof(struct ABC *) ); for (int i = 0; i < 10; i++) { (*tp)[i] = malloc( 10 * sizeof(struct ABC) ); } } .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * ``*tp[]`` is a single pointer and will point to array of structures * Step 3: Define a single pointer .. code-block:: c struct ABC { int a; int b; int c; }; struct ABC **dp; * Step 4 : Pass double pointer "dp" by reference .. code-block:: c get_memory(&dp); * Step 5 : Assign values to array of structures from dp[0][0] to dp[9][9] .. code-block:: c for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { dp[i][j].a = ++val; } } * Step 6 : Print the structures from dp[0][0] to dp[9][9] .. code-block:: c for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { printf("dp[%d][%d].a = %d\n", i, j, dp[i][j].a); } } * Step 7 : Free after use .. code-block:: c for (int i = 0; i < 10; i++) { free(dp[i]); } free(dp); * See the full program below .. code-block:: c :linenos: :emphasize-lines: 17, 22, 29, 33, 40, 49, 56, 59 #include #include // Step 1 : Include stdlib.h #include struct ABC { int a; int b; int c; }; // Step 2 : Define an allocation function void get_memory(struct ABC ***tp) { // Step 2.1 : Create Ten Single Pointers from tp[0] ... tp[9] *tp = malloc( 10 * sizeof(struct ABC *) ); // Step 2.2 : Create Ten Characters in every Row for (int i = 0; i < 10; i++) { (*tp)[i] = malloc( 10 * sizeof(struct ABC) ); } } int main(void) { // Step 3: Define a single pointer struct ABC **dp; int val = 0; // Step 4 : Pass double pointer "dp" by reference get_memory(&dp); // Step 5 : Assign strings to array of structures for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { dp[i][j].a = ++val; } } // Step 6 : Print the strings for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { printf("dp[%d][%d].a = %d\n", i, j, dp[i][j].a); } } // Step 7 : Free after use for (int i = 0; i < 10; i++) { free(dp[i]); } free(dp); return 0; } .. card:: See Also * Current Module * :doc:`../malloc_ptr` * Previous Module * :doc:`../../array_n_ptrs/array_n_ptrs` * Next Module * :doc:`../../typecasting_n_ptr/typecasting_n_ptr` * Other Modules * :doc:`../../variable_and_ptr/variable_and_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`