Malloc int 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:`Create a heterogeneous 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 integers .. 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 .. _int_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 int **ptr; * Step 3 : Create One single pointer .. code-block:: c ptr = malloc( sizeof(int *) ); .. 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 integer .. code-block:: c *ptr = malloc( sizeof(int) ); OR .. code-block:: c ptr[0] = malloc( sizeof(int) ); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Allocates 4 Bytes of memory in heap * Step 5 : Assign value to Integer .. code-block:: c **ptr = 65; OR .. code-block:: c *ptr[0] = 65; OR .. code-block:: c ptr[0][0] = 65; * Step 6 : Print the value .. code-block:: c printf("**ptr = %d\n", **ptr); printf("*ptr[0] = %d\n", *ptr[0]); printf("ptr[0][0] = %d\n", ptr[0][0]); * 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: 9, 12, 15, 24, 25 #include // Step 1 : Include stdlib.h #include int main(void) { // Step 2 : Define Double pointer int **ptr; // Step 3 : Create One single pointer ptr = malloc( sizeof(int *) ); // Step 4 : Create One single integer *ptr = malloc( sizeof(int) ); // Step 5 : Assign value to integer **ptr = 65; // Step 6 : Print the value printf("**ptr = %d\n", **ptr); // 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(int \*) ) * ``ptr`` points to array of single pointers \*ptr = malloc( sizeof(int ) ) * ``*ptr`` points to array of integers 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) * 4 Bytes * Fully dereferenced * Hence takes the size of actual type =========================================== ============================================================= .. _int_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 int **ptr; * Step 3 : Create One single pointer .. code-block:: c ptr = malloc( sizeof(int *) ); .. 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 integers .. code-block:: c *ptr = malloc( 10 * sizeof(int) ); OR .. code-block:: c ptr[0] = malloc( 10 * sizeof(int) ); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Allocates 40 Bytes of memory in heap OR .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Allocates 10 Integers of memory in heap * Step 5 : \*ptr can be used as an array of Integers now ! .. code-block:: c int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; memcpy(*ptr, arr, sizeof(arr)); * Step 6 : Print individual integers : Using (\*ptr)[i] .. code-block:: c for (int i = 0; i < 10; i++) { printf("%d\n", (*ptr)[i]); } * Step 8 : Print individual integers : Using ptr[0][i] .. code-block:: c for (int i = 0; i < 10; i++) { printf("%d\n", ptr[0][i]); } * Step 9 : 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: 12, 15, 19, 25, 32, 36, 37 #include // Step 1 : Include stdlib.h #include int main(void) { // Step 2 : Define Double pointer int **ptr; // Step 3 : Create One single pointer ptr = malloc( sizeof(int *) ); // Step 4 : Create Ten integers *ptr = malloc( 10 * sizeof(int) ); // Step 5 : *ptr is now pointing to array of integers int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; memcpy(*ptr, arr, sizeof(arr)); // Step 6 : Print individual Integers : Using (*ptr)[i] printf("\nMethod 2 : Print Integers using (*ptr)[i]\n"); for (int i = 0; i < 10; i++) { printf("%d\n", (*ptr)[i]); } // Step 8 : Print individual Integers : Using ptr[0][i] printf("\nMethod 2 : Print Integers using ptr[0][i]\n"); for (int i = 0; i < 10; i++) { printf("%d\n", ptr[0][i]); } // Step 9 : Free after use free(*ptr); free(ptr); return 0; } .. tab-set:: .. tab-item:: Summary of 1,10 array =========================================== ============================================================= Statement Description =========================================== ============================================================= ptr = malloc( sizeof(int \*) ) * ``ptr`` points to array of single pointers \*ptr = malloc( 10 * sizeof(int) ) * ``*ptr`` points to array of integers 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) * 4 Bytes * Fully dereferenced * Hence takes the size of actual type \*ptr * Points to array of 10 integers (\*ptr)[i] * Method 1 : To access individual integers ptr[0][i] * Method 2 : To access individual integers =========================================== ============================================================= .. _int_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 int **ptr; * Step 3 : Create Ten Single Pointers from ptr[0] ... ptr[9] .. code-block:: c ptr = malloc( 10 * sizeof(int *) ); * Step 4 : Create One Integer in every Row .. code-block:: c for (int i = 0; i < 10; i++) { ptr[i] = malloc( sizeof(int) ); } * Step 5 : Assign values to Integers .. code-block:: c for (int i = 0; i < 10; i++) { ptr[i][0] = ++val; } * Step 6 : Print the values .. code-block:: c for (int i = 0; i < 10; i++) { printf("Row %d Column 0 : %d\n", i, ptr[i][0]); } * 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: 7, 11, 16, 22, 28, 34, 37 // Step 1 : Include stdlib.h #include int main(void) { // Step 2 : Define Double pointer int **ptr; int val = 0; // Step 3 : Create Ten Single Pointers from ptr[0] ... ptr[9] ptr = malloc( 10 * sizeof(int *) ); // Step 4 : Create One Character in every Row for (int i = 0; i < 10; i++) { ptr[i] = malloc( sizeof(int) ); } // Step 5 : Assign values to integers for (int i = 0; i < 10; i++) { ptr[i][0] = ++val; } // Step 6 : Print the values for (int i = 0; i < 10; i++) { printf("Row %d Column 0 : %d\n", i, ptr[i][0]); } // Step 7 : Free after use for (int i = 0; i < 10; i++) { free(ptr[i]); } free(ptr); return 0; } .. _int_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 int **ptr; * Step 3 : Create Ten Single Pointers from ptr[0] ... ptr[9] .. code-block:: c ptr = malloc( 10 * sizeof(int *) ); * Step 4 : Create Ten Integers in every Row .. code-block:: c for (int i = 0; i < 10; i++) { ptr[i] = malloc( 10 * sizeof(int) ); } * Step 5 : Assign values to array of integers .. code-block:: c for (int i = 0; i < 10; i++) { int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; memcpy(ptr[i], arr, sizeof(arr)); } * Step 6 : Print the integers .. code-block:: c for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { printf("Row %d : Col %d : Integer : %d\n", i, j, ptr[i][j] ); } } * 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: 9, 13, 18, 28, 36, 43, 46 #include // Step 1 : Include stdlib.h #include int main(void) { // Step 2 : Define Double pointer int **ptr; int val = 0; // Step 3 : Create Ten Single Pointers from ptr[0] ... ptr[9] ptr = malloc( 10 * sizeof(int *) ); // Step 4 : Create Ten Characters in every Row for (int i = 0; i < 10; i++) { ptr[i] = malloc( 10 * sizeof(int) ); } //ptr[0] is an array of 10 integers. Same is true for ptr[1] to ptr[9] // Step 5 : Assign values to array of integers for (int i = 0; i < 10; i++) { int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; memcpy(ptr[i], arr, sizeof(arr)); } // Step 6 : Print the integers for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { printf("Row %d : Col %d : Integer : %d\n", i, j, ptr[i][j] ); } } // Step 7 : Free after use for (int i = 0; i < 10; i++) { free(ptr[i]); } free(ptr); return 0; } .. _int_dp_5x_hetero_array: .. tab-set:: .. tab-item:: Heterogeneous Arrays : Where Every Row has unequal number of blocks * Example is ``arr`` has 5 rows, and * arr[0] points to an array of 7 integers * arr[1] points to an array of 5 integers * arr[2] points to an array of 4 integers * arr[3] points to an array of 9 integers * arr[4] points to an array of 3 integers .. tab-set:: .. tab-item:: Create 5 Rows : Every Row has different number of integers * Step 1 : Include stdlib.h .. code-block:: c #include * Step 2 : Define Double pointer .. code-block:: c int **arr; * Step 3 : Create Five Single Pointers from arr[0] ... arr[4] .. code-block:: c arr = malloc( 5 * sizeof(int *) ); * Step 4 : Create Character arrays in every Row .. code-block:: c arr[0] = malloc( 7 * sizeof(int) ); arr[1] = malloc( 5 * sizeof(int) ); arr[2] = malloc( 4 * sizeof(int) ); arr[3] = malloc( 9 * sizeof(int) ); arr[4] = malloc( 3 * sizeof(int) ); * Step 5 : Copy integers to array of integers .. code-block:: c int i_arr_0[7] = {1, 2, 3, 4, 5, 6, 7}; memcpy(arr[0], i_arr_0, sizeof(iarr)); int i_arr_1[5] = {1, 2, 3, 4, 5}; memcpy(arr[1], i_arr_1, sizeof(iarr)); int i_arr_2[4] = {1, 2, 3, 4}; memcpy(arr[2], i_arr_2, sizeof(iarr)); int i_arr_3[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; memcpy(arr[3], i_arr_3, sizeof(iarr)); int i_arr_4[3] = {1, 2, 3}; memcpy(arr[4], i_arr_4, sizeof(iarr)); * Step 6 : Print the integers .. code-block:: c for (int i = 0; i < 7; i++) { printf("arr[0][i] = %d\n", i, arr[0][i]); } for (int i = 0; i < 5; i++) { printf("arr[1][i] = %d\n", i, arr[1][i]); } for (int i = 0; i < 4; i++) { printf("arr[2][i] = %d\n", i, arr[2][i]); } for (int i = 0; i < 9; i++) { printf("arr[3][i] = %d\n", i, arr[3][i]); } for (int i = 0; i < 3; i++) { printf("arr[4][i] = %d\n", i, arr[4][i]); } * Step 7 : Free after use .. code-block:: c for (int i = 0; i < 5; i++) { free(arr[i]); } free(arr); * See the full program below .. code-block:: c :linenos: :emphasize-lines: 9, 12, 15, 16, 17, 18, 19, 68, 71 #include // Step 1 : Include stdlib.h #include int main(void) { // Step 2 : Define Double pointer int **arr; // Step 3 : Create Five Single Pointers from arr[0] ... arr[4] arr = malloc( 5 * sizeof(int *) ); // Step 4 : Create Character arrays in every Row arr[0] = malloc( 7 * sizeof(int) ); arr[1] = malloc( 5 * sizeof(int) ); arr[2] = malloc( 4 * sizeof(int) ); arr[3] = malloc( 9 * sizeof(int) ); arr[4] = malloc( 3 * sizeof(int) ); // Step 5 : Copy integers to array of integers int i_arr_0[7] = {1, 2, 3, 4, 5, 6, 7}; memcpy(arr[0], i_arr_0, sizeof(i_arr_0)); int i_arr_1[5] = {1, 2, 3, 4, 5}; memcpy(arr[1], i_arr_1, sizeof(i_arr_1)); int i_arr_2[4] = {1, 2, 3, 4}; memcpy(arr[2], i_arr_2, sizeof(i_arr_2)); int i_arr_3[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; memcpy(arr[3], i_arr_3, sizeof(i_arr_3)); int i_arr_4[3] = {1, 2, 3}; memcpy(arr[4], i_arr_4, sizeof(i_arr_4)); // Step 6 : Print the integers for (int i = 0; i < 7; i++) { printf("arr[0][%d] = %d\n", i, arr[0][i]); } for (int i = 0; i < 5; i++) { printf("arr[1][%d] = %d\n", i, arr[1][i]); } for (int i = 0; i < 4; i++) { printf("arr[2][%d] = %d\n", i, arr[2][i]); } for (int i = 0; i < 9; i++) { printf("arr[3][%d] = %d\n", i, arr[3][i]); } for (int i = 0; i < 3; i++) { printf("arr[4][%d] = %d\n", i, arr[4][i]); } // Step 7 : Free after use for (int i = 0; i < 5; i++) { free(arr[i]); } free(arr); return 0; } .. _int_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(int **dp) { // *dp is equal to sp in caller *dp = malloc(10 * sizeof(int)); memset(*dp, 0, 10); } * Step 3: Define a single pointer .. code-block:: c int *sp; * Step 4 : Pass single pointer ``sp`` by reference .. code-block:: c get_memory(&sp); * Step 5 : ``sp`` is now pointing to array of 10 integers .. code-block:: c int i_arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; memcpy(sp, i_arr, sizeof(i_arr)); * Step 6 : Free the memory .. code-block:: c free(sp); * See full program below .. code-block:: c :linenos: :emphasize-lines: 10, 21, 25, 28, 32 #include // Step 1 : Include stdlib.h #include // Step 2 : Define an allocation function void get_memory(int **dp) { // *dp is equal to sp in caller *dp = malloc(10 * sizeof(int)); memset(*dp, 0, 10); } int main(void) { // Step 3: Define a single pointer int *sp; // Step 4 : Pass single pointer "sp" by reference get_memory(&sp); // Step 5 : "sp" is now pointing to array of 10 integers int i_arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; memcpy(sp, i_arr, sizeof(i_arr)); for (int i = 0; i < 10; i++) { printf("Row:%d : Integer:%d\n", i, sp[i]); } // Step 6 : Free the memory free(sp); return 0; } .. _int_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(int ***tp) { } * Step 2.1 : Create Ten Single Pointers from tp[0] ... tp[9] .. code-block:: c :emphasize-lines: 3 void get_memory(int ***tp) { *tp = malloc( 10 * sizeof(int *) ); } .. 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(int ***tp) { *tp = malloc( 10 * sizeof(int *) ); for (int i = 0; i < 10; i++) { (*tp)[i] = malloc( 10 * sizeof(int) ); } } .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * ``*tp[]`` is a single pointer and will point to array of integers * Step 3: Define a single pointer .. code-block:: c int **dp; * Step 4 : Pass double pointer "dp" by reference .. code-block:: c get_memory(&dp); * Step 5 : Assign integers to array of integers .. code-block:: c int val = 0; for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { dp[i][j] = ++val; } } * Step 6 : Print the integers .. code-block:: c for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { printf("Row:%d : Col:%d : Integer:%d\n", i, j, dp[i][j]); } } * 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: 10, 15, 26, 33, 42, 49, 52 #include // Step 1 : Include stdlib.h #include // Step 2 : Define an allocation function void get_memory(int ***tp) { // Step 2.1 : Create Ten Single Pointers from tp[0] ... tp[9] *tp = malloc( 10 * sizeof(int *) ); // Step 2.2 : Create Ten Characters in every Row for (int i = 0; i < 10; i++) { (*tp)[i] = malloc( 10 * sizeof(int) ); } } int main(void) { // Step 3: Define a single pointer int **dp; int val = 0; // Step 4 : Pass double pointer "dp" by reference get_memory(&dp); // Step 5 : Assign integers to array of integers for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { dp[i][j] = ++val; } } // Step 6 : Print the integers for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { printf("Row:%d : Col:%d : Integer:%d\n", i, j, dp[i][j]); } } // 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`