Malloc char 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 characters .. 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 .. _char_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 char **ptr; * Step 3 : Create One single pointer .. code-block:: c ptr = malloc( sizeof(char *) ); .. 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 character .. code-block:: c *ptr = malloc( sizeof(char) ); OR .. code-block:: c ptr[0] = malloc( sizeof(char) ); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Allocates 1 Byte of memory in heap * Step 5 : Assign value to character .. 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: 12, 15, 24, 25 #include // Step 1 : Include stdlib.h #include int main(void) { // Step 2 : Define Double pointer char **ptr; // Step 3 : Create One single pointer ptr = malloc( sizeof(char *) ); // Step 4 : Create One single character *ptr = malloc( sizeof(char) ); // Step 5 : Assign value to character **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(char \*) ) * ``ptr`` points to array of single pointers \*ptr = malloc( sizeof(char ) ) * ``*ptr`` points to array of characters 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) * 1 Byte * Fully dereferenced * Hence takes the size of actual type =========================================== ============================================================= .. _char_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 char **ptr; * Step 3 : Create One single pointer .. code-block:: c ptr = malloc( sizeof(char *) ); .. 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 characters .. code-block:: c *ptr = malloc( 10 * sizeof(char) ); OR .. code-block:: c ptr[0] = malloc( 10 * sizeof(char) ); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Allocates 10 Bytes of memory in heap * Step 5 : \*ptr can be used as an array of characters now ! .. code-block:: c memset(*ptr, 0, 10); strcpy(*ptr, "Laptop"); * Step 6 : Print the string .. code-block:: c printf("*ptr = %s\n", *ptr); * Step 7 : Print individual characters : Using (\*ptr)[i] .. code-block:: c for (int i = 0; i < 10; i++) { printf("%c", (*ptr)[i]); } * Step 8 : Print individual characters : Using ptr[0][i] .. code-block:: c for (int i = 0; i < 10; i++) { printf("%c", 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: 13, 16, 20, 24, 30, 37, 41, 42 #include #include // Step 1 : Include stdlib.h #include int main(void) { // Step 2 : Define Double pointer char **ptr; // Step 3 : Create One single pointer ptr = malloc( sizeof(char *) ); // Step 4 : Create Ten characters *ptr = malloc( 10 * sizeof(char) ); // Step 5 : *ptr is now pointing to array of chracters memset(*ptr, 0, 10); strcpy(*ptr, "Laptop"); // Step 6 : Print the string using %s printf("\nMethod 1 : Print all characters using *ptr\n"); printf("*ptr = %s\n", *ptr); // Step 7 : Print individual characters : Using (*ptr)[i] printf("\nMethod 2 : Print characters using (*ptr)[i]\n"); for (int i = 0; i < 10; i++) { printf("%c", (*ptr)[i]); } // Step 8 : Print individual characters : Using ptr[0][i] printf("\nMethod 2 : Print characters using ptr[0][i]\n"); for (int i = 0; i < 10; i++) { printf("%c", 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(char \*) ) * ``ptr`` points to array of single pointers \*ptr = malloc( 10 * sizeof(char) ) * ``*ptr`` points to array of characters 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) * 1 Byte * Fully dereferenced * Hence takes the size of actual type \*ptr * Points to array of 10 characters strcpy(\*ptr, "Laptop"); * Copies string "Laptop" to \*ptr (\*ptr)[i] * Method 1 : To access individual characters ptr[0][i] * Method 2 : To access individual characters =========================================== ============================================================= .. _char_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 char **ptr; * Step 3 : Create Ten Single Pointers from ptr[0] ... ptr[9] .. code-block:: c ptr = malloc( 10 * sizeof(char *) ); * Step 4 : Create One Character in every Row .. code-block:: c for (int i = 0; i < 10; i++) { ptr[i] = malloc( sizeof(char) ); } * Step 5 : Assign values to characters .. 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: 9, 13, 18, 24, 30, 36, 39 #include // Step 1 : Include stdlib.h #include int main(void) { // Step 2 : Define Double pointer char **ptr; int val = 0; // Step 3 : Create Ten Single Pointers from ptr[0] ... ptr[9] ptr = malloc( 10 * sizeof(char *) ); // Step 4 : Create One Character in every Row for (int i = 0; i < 10; i++) { ptr[i] = malloc( sizeof(char) ); } // Step 5 : Assign values to characters 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; } .. _char_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 char **ptr; * Step 3 : Create Ten Single Pointers from ptr[0] ... ptr[9] .. code-block:: c ptr = malloc( 10 * sizeof(char *) ); * Step 4 : Create Ten Characters in every Row .. code-block:: c for (int i = 0; i < 10; i++) { ptr[i] = malloc( 10 * sizeof(char) ); } * Step 5 : Assign strings to array of characters .. code-block:: c for (int i = 0; i < 10; i++) { sprintf(ptr[i], "Laptop %d", ++val); } * Step 6 : Print the strings .. code-block:: c for (int i = 0; i < 10; i++) { printf("Row %d string : %s\n", i, ptr[i]); } * 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: 10, 14, 19, 27, 33, 39, 42 #include #include // Step 1 : Include stdlib.h #include int main(void) { // Step 2 : Define Double pointer char **ptr; int val = 0; // Step 3 : Create Ten Single Pointers from ptr[0] ... ptr[9] ptr = malloc( 10 * sizeof(char *) ); // Step 4 : Create Ten Characters in every Row for (int i = 0; i < 10; i++) { ptr[i] = malloc( 10 * sizeof(char) ); } //ptr[0] is an array of 10 characters. Same is true for ptr[1] to ptr[9] // Step 5 : Assign strings to array of characters for (int i = 0; i < 10; i++) { sprintf(ptr[i], "Laptop %d", ++val); } // Step 6 : Print the strings for (int i = 0; i < 10; i++) { printf("Row %d string : %s\n", i, ptr[i]); } // Step 7 : Free after use for (int i = 0; i < 10; i++) { free(ptr[i]); } free(ptr); return 0; } .. _char_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 characters * arr[1] points to an array of 5 characters * arr[2] points to an array of 4 characters * arr[3] points to an array of 9 characters * arr[4] points to an array of 3 characters .. tab-set:: .. tab-item:: Create 5 Rows : Every Row has different number of characters * Step 1 : Include stdlib.h .. code-block:: c #include * Step 2 : Define Double pointer .. code-block:: c char **arr; * Step 3 : Create Five Single Pointers from arr[0] ... arr[4] .. code-block:: c arr = malloc( 5 * sizeof(char *) ); * Step 4 : Create Character arrays in every Row .. code-block:: c arr[0] = malloc( 7 * sizeof(char) ); arr[1] = malloc( 5 * sizeof(char) ); arr[2] = malloc( 4 * sizeof(char) ); arr[3] = malloc( 9 * sizeof(char) ); arr[4] = malloc( 3 * sizeof(char) ); * Step 5 : Copy strings to array along with '\\0' .. code-block:: c sprintf(arr[0], "Adam12"); sprintf(arr[1], "John"); sprintf(arr[2], "abc"); sprintf(arr[3], "12345678"); sprintf(arr[4], "Hi"); * Step 6 : Print the strings .. code-block:: c for (int i = 0; i < 5; i++) { printf("Row %d string : %s\n", i, arr[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: 10, 13, 32, 38, 41 #include #include // Step 1 : Include stdlib.h #include int main(void) { // Step 2 : Define Double pointer char **arr; // Step 3 : Create Five Single Pointers from arr[0] ... arr[4] arr = malloc( 5 * sizeof(char *) ); // Step 4 : Create Character arrays in every Row arr[0] = malloc( 7 * sizeof(char) ); arr[1] = malloc( 5 * sizeof(char) ); arr[2] = malloc( 4 * sizeof(char) ); arr[3] = malloc( 9 * sizeof(char) ); arr[4] = malloc( 3 * sizeof(char) ); // Step 5 : Copy strings to array along with '\0' sprintf(arr[0], "Adam12"); sprintf(arr[1], "John"); sprintf(arr[2], "abc"); sprintf(arr[3], "12345678"); sprintf(arr[4], "Hi"); // Step 6 : Print the strings for (int i = 0; i < 5; i++) { printf("Row %d string : %s\n", i, arr[i]); } // Step 7 : Free after use for (int i = 0; i < 5; i++) { free(arr[i]); } free(arr); return 0; } .. _char_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(char **dp) { // *dp is equal to sp in caller *dp = malloc(10 * sizeof(char)); memset(*dp, 0, 10); } * Step 3: Define a single pointer .. code-block:: c char *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 characters .. code-block:: c strcpy(sp, "Laptop 12"); * Step 6 : Free the memory .. code-block:: c free(sp); * See full program below .. code-block:: c :linenos: :emphasize-lines: 11, 22, 30 #include #include // Step 1 : Include stdlib.h #include // Step 2 : Define an allocation function void get_memory(char **dp) { // *dp is equal to sp in caller *dp = malloc(10 * sizeof(char)); memset(*dp, 0, 10); } int main(void) { // Step 3: Define a single pointer char *sp; // Step 4 : Pass single pointer "sp" by reference get_memory(&sp); // Step 5 : "sp" is now pointing to array of 10 characters strcpy(sp, "Laptop 12"); printf("String is %s\n", sp); // Step 6 : Free the memory free(sp); return 0; } .. _char_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(char ***tp) { } * Step 2.1 : Create Ten Single Pointers from tp[0] ... tp[9] .. code-block:: c :emphasize-lines: 3 void get_memory(char ***tp) { *tp = malloc( 10 * sizeof(char *) ); } .. 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(char ***tp) { *tp = malloc( 10 * sizeof(char *) ); for (int i = 0; i < 10; i++) { (*tp)[i] = malloc( 10 * sizeof(char) ); } } .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * ``*tp[]`` is a single pointer and will point to array of characters * Step 3: Define a single pointer .. code-block:: c char **dp; * Step 4 : Pass double pointer "dp" by reference .. code-block:: c get_memory(&dp); * Step 5 : Assign strings to array of characters .. code-block:: c for (int i = 0; i < 10; i++) { sprintf(dp[i], "Laptop %d", ++val); } * Step 6 : Print the strings .. code-block:: c for (int i = 0; i < 10; i++) { printf("Row %d string : %s\n", i, dp[i]); } * 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: 11, 16, 27, 44, 47 #include #include // Step 1 : Include stdlib.h #include // Step 2 : Define an allocation function void get_memory(char ***tp) { // Step 2.1 : Create Ten Single Pointers from tp[0] ... tp[9] *tp = malloc( 10 * sizeof(char *) ); // Step 2.2 : Create Ten Characters in every Row for (int i = 0; i < 10; i++) { (*tp)[i] = malloc( 10 * sizeof(char) ); } } int main(void) { // Step 3: Define a single pointer char **dp; int val = 0; // Step 4 : Pass double pointer "dp" by reference get_memory(&dp); // Step 5 : Assign strings to array of characters for (int i = 0; i < 10; i++) { sprintf(dp[i], "Laptop %d", ++val); } // Step 6 : Print the strings for (int i = 0; i < 10; i++) { printf("Row %d string : %s\n", i, dp[i]); } // 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`