Basics of Character 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 Value : Wrong Usage ` * :ref:`1 Double Pointer : Pass by Reference ` .. _basic_ptr_char_dp_sp_ex1: .. tab-set:: .. tab-item:: 1 Double Pointer, 1 Single Pointer : Simple variables * Step 1 : Define a character .. code-block:: c char c = 65; * Step 2 : Define a Single Pointer .. code-block:: c char *sp = &c; OR .. code-block:: c char *sp; sp = &c; * Step 3 : Define a Double Pointer .. code-block:: c char **dp = &sp; OR .. code-block:: c char **dp; dp = &sp; * Step 4 : Access user data (in this case character) using single pointer .. code-block:: c printf("c = %d\n", *sp); * Step 5 : Access user data (in this case character) 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 character ``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) { char c = 65; char *sp = &c; char **dp = &sp; printf("c = %d\n", c); printf("*sp = %d\n", *sp); printf("**dp = %d\n", **dp); char 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_char_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 characters .. code-block:: c char arr[] = "Laptop"; * Step 2 : Define a single pointer .. code-block:: c char *sp = arr; OR .. code-block:: c char *sp; sp = arr; OR .. code-block:: c char *sp; sp = &arr[0]; * Step 3 : Define a double pointer .. code-block:: c char **dp = &sp; OR .. code-block:: c char **dp; dp = &sp; * Step 4 : Access user data (in this case array of characters) using single pointer variable ``sp`` .. code-block:: c printf("arr = %s\n", sp); * Step 5 : Access user data (in this case array of characters) using double pointer variable ``dp`` .. code-block:: c printf("arr = %s\n", *dp); .. 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) { char arr[] = "Laptop"; char *sp = arr; char **dp = &sp; //Access full array printf("arr = %s\n", arr); printf("sp = %s\n", sp); printf("*dp = %s\n", *dp); //Access individual character printf("arr[3] = %c\n", arr[3]); printf("sp[3] = %c\n", sp[3]); printf("(*dp)[3] = %c\n", (*dp)[3]); return 0; } * Output is as below .. code-block:: c arr = Laptop sp = Laptop *dp = Laptop arr[3] = t sp[3] = t (*dp)[3] = t .. _basic_ptr_char_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 char *sp; * Step 2 : Allocate heap memory to single pointer .. code-block:: c sp = malloc(10 * sizeof(char)); * Step 3 : Copy User data to heap memory .. code-block:: c strcpy(sp, "Laptop"); * Step 4 : Define a double pointer .. code-block:: c char **dp; dp = &sp; * Step 5 : Access User data using single pointer variable ``sp`` .. code-block:: c printf("arr = %s\n", sp); printf("arr[3] = %c\n", sp[3]); * Step 6 : Access User data using double pointer variable ``dp`` .. code-block:: c printf("arr = %s\n", *dp); printf("arr[3] = %c\n", (*dp)[3]); * See full program below .. code-block:: c #include #include #include int main(void) { char *sp; sp = malloc(10 * sizeof(char)); strcpy(sp, "Laptop"); char **dp; dp = &sp; //Access full array printf("arr = %s\n", sp); printf("arr = %s\n", *dp); //Access individual character printf("arr[3] = %c\n", sp[3]); printf("arr[3] = %c\n", (*dp)[3]); free(sp); return 0; } * Output is as below .. code-block:: c .. _basic_ptr_char_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 char **dp; * Step 2 : Allocate memory to a double pointer .. code-block:: c dp = malloc(sizeof(char *)); * Step 3 : Allocate memory to a single pointer .. code-block:: c *dp = malloc(sizeof(char)); * Step 4 : Store user data .. code-block:: c **dp = 65; * Step 5 : Read user data .. code-block:: c printf("User data = %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) { char **dp; dp = malloc(sizeof(char *)); *dp = malloc(sizeof(char)); **dp = 65; printf("User data = %d\n", **dp); free(*dp); free(dp); return 0; } .. _basic_ptr_char_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 char **dp; * Step 2 : Allocate memory to a double pointer .. code-block:: c dp = malloc(sizeof(char *)); * Step 3 : Allocate memory to a single pointer .. code-block:: c *dp = malloc(10 * sizeof(char)); * Step 4 : Copy User data to heap .. code-block:: c strcpy(*dp, "Laptop"); * Step 5 : Read user data from heap .. code-block:: c printf("User data = %s\n", *dp); for (int i = 0; i < 10; i++) { printf("User data = %c\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) { char **dp; dp = malloc(sizeof(char *)); *dp = malloc(10 * sizeof(char)); memset(*dp, 0, 10); strcpy(*dp, "Laptop"); printf("User data = %s\n", *dp); for (int i = 0; i < 10; i++) { printf("User data = %c\n", (*dp)[i]); } free(*dp); free(dp); return 0; } .. _basic_ptr_char_dp_sp_ex6: .. tab-set:: .. tab-item:: 1 Double Pointer : Pointing to array of single pointers : Static * Step 1 : Define 3 Single dimension character arrays .. code-block:: c char arr0[32] = "Laptop"; char arr1[32] = "Mouse"; char arr2[32] = "Keyboard"; * Step 2 : Define array of single pointers .. code-block:: c char *sp_arr[] = {arr0, arr1, arr2}; * Step 3 : Define a double pointer .. code-block:: c char **dp; dp = sp_arr; * Step 4 : Use ``dp`` to change contents of single dimension arrays .. code-block:: c strcpy(dp[0], "New Laptop"); strcpy(dp[1], "New Mouse"); strcpy(dp[2], "New Keyboard"); * Step 5 : Use ``sp_arr`` to access contents of single dimension arrays .. code-block:: c printf("arr0 = %s\n", sp_arr[0]); printf("arr1 = %s\n", sp_arr[1]); printf("arr2 = %s\n", sp_arr[2]); * Step 6 : Use ``dp`` to access contents of single dimension arrays .. code-block:: c printf("arr0 = %s\n", dp[0]); printf("arr1 = %s\n", dp[1]); printf("arr2 = %s\n", dp[2]); * See full program below .. code-block:: c #include #include #include int main(void) { char arr0[32] = "Laptop"; char arr1[32] = "Mouse"; char arr2[32] = "Keyboard"; char *sp_arr[] = {arr0, arr1, arr2}; char **dp; dp = sp_arr; strcpy(dp[0], "New Laptop"); strcpy(dp[1], "New Mouse"); strcpy(dp[2], "New Keyboard"); printf("arr0 = %s\n", sp_arr[0]); printf("arr0 = %s\n", dp[0]); printf("arr1 = %s\n", sp_arr[1]); printf("arr1 = %s\n", dp[1]); printf("arr2 = %s\n", sp_arr[2]); printf("arr2 = %s\n", dp[2]); return 0; } .. _basic_ptr_char_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 char **dp; * Step 2 : Allocate heap memory : Create 3 single pointers ``dp[0]``, ``dp[1]``, ``dp[2]`` .. code-block:: c dp = malloc(3 * sizeof(char *)); * Step 3 : Allocate heap memory : Create 3 single dimension character arrays of size 32 characters each .. code-block:: c dp[0] = malloc(32 * sizeof(char)); dp[1] = malloc(32 * sizeof(char)); dp[2] = malloc(32 * sizeof(char)); * Step 4 : Store user data .. code-block:: c strcpy(dp[0], "New Laptop"); strcpy(dp[1], "New Mouse"); strcpy(dp[2], "New Keyboard"); * Step 5 : Access user data .. code-block:: c printf("string 0 = %s\n", dp[0]); printf("string 1 = %s\n", dp[1]); printf("string 2 = %s\n", dp[2]); * Step 6 : Free 3 character arrays .. code-block:: c free(dp[0]); free(dp[1]); free(dp[2]); * Step 7 : Free 3 single pointers .. code-block:: c free(dp); * See full program below .. code-block:: c #include #include #include int main(void) { char **dp; dp = malloc(3 * sizeof(char *)); dp[0] = malloc(32 * sizeof(char)); dp[1] = malloc(32 * sizeof(char)); dp[2] = malloc(32 * sizeof(char)); strcpy(dp[0], "New Laptop"); strcpy(dp[1], "New Mouse"); strcpy(dp[2], "New Keyboard"); printf("string 0 = %s\n", dp[0]); printf("string 1 = %s\n", dp[1]); printf("string 2 = %s\n", dp[2]); free(dp[0]); free(dp[1]); free(dp[2]); free(dp); return 0; } .. _basic_ptr_char_dp_sp_ex8: .. tab-set:: .. tab-item:: 1 Double Pointer : Pass by Value : Wrong usage * In this example, * Programmer is defining a function called ``fun`` which takes care of allocation * Plans to use the allocated memory in function ``main`` * But pointer ``dp`` is passed by value to function ``fun`` * Which means there are two pointers, ``dp`` and ``dp_v`` * Any assignement done to ``dp_v`` will not affect ``dp`` in caller * Hence, below program crashes inside function ``main`` when first ``strcpy`` is tried * See full program below .. code-block:: c #include #include #include void fun(char **dp_v) { dp_v = malloc(3 * sizeof(char *)); dp_v[0] = malloc(32 * sizeof(char)); dp_v[1] = malloc(32 * sizeof(char)); dp_v[2] = malloc(32 * sizeof(char)); } int main(void) { char **dp; fun(dp); strcpy(dp[0], "New Laptop"); strcpy(dp[1], "New Mouse"); strcpy(dp[2], "New Keyboard"); printf("dp[0] = %s\n", dp[0]); printf("dp[1] = %s\n", dp[1]); printf("dp[2] = %s\n", dp[2]); free(dp[0]); free(dp[1]); free(dp[2]); free(dp); return 0; } .. _basic_ptr_char_dp_sp_ex9: .. tab-set:: .. tab-item:: 1 Double Pointer : Pass by Reference * In order to fix the problem mentioned in above case, let us pass double pointer by reference * Step 1 : Define a double pointer .. code-block:: c char **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(char ***dp_r) { *dp_r = malloc(3 * sizeof(char *)); (*dp_r)[0] = malloc(32 * sizeof(char)); (*dp_r)[1] = malloc(32 * sizeof(char)); (*dp_r)[2] = malloc(32 * sizeof(char)); } * Step 4 : Use single pointers dp[0], dp[1], dp[2] in caller to store user data .. code-block:: c strcpy(dp[0], "New Laptop"); strcpy(dp[1], "New Mouse"); strcpy(dp[2], "New Keyboard"); * Step 5 : Use single pointers dp[0], dp[1], dp[2] in caller to access user data .. code-block:: c printf("dp[0] = %s\n", dp[0]); printf("dp[1] = %s\n", dp[1]); printf("dp[2] = %s\n", dp[2]); * Step 6 : Free 3 arrays of characters after use .. code-block:: c free(dp[0]); free(dp[1]); free(dp[2]); * 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(char ***dp_r) { *dp_r = malloc(3 * sizeof(char *)); (*dp_r)[0] = malloc(32 * sizeof(char)); (*dp_r)[1] = malloc(32 * sizeof(char)); (*dp_r)[2] = malloc(32 * sizeof(char)); } int main(void) { char **dp; fun(&dp); strcpy(dp[0], "New Laptop"); strcpy(dp[1], "New Mouse"); strcpy(dp[2], "New Keyboard"); printf("dp[0] = %s\n", dp[0]); printf("dp[1] = %s\n", dp[1]); printf("dp[2] = %s\n", dp[2]); free(dp[0]); free(dp[1]); free(dp[2]); free(dp); return 0; } .. 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`