Malloc Advanced Combinations ============================== * In this section, you are going to learn .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to do malloc() for pointers inside structures ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to do malloc() for pointers inside nested structures ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to read from memory using pointers inside structures ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow How to write to memory using pointers inside structures ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Topics in this section, * :ref:`integer pointer inside structure ` * :ref:`integer pointer inside nested structure : Single pointer ` * :ref:`integer pointer inside nested structure : Double Pointer ` .. tab-set:: .. tab-item:: Steps for Malloc : For structures containing pointers .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Step 1 : Count number of Pointers. Number of Pointers is equal to Number of minimum Mallocs For example, there are two pointers ``ptr`` and ``*ptr`` in below code snippet .. code-block:: c struct ABC **ptr; Hence, we require minimum of two mallocs before we access members inside structure .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Step 2 : Allocate from outermost pointer .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Step 3 : Dereference for Read/Write. * If there are N pointers we can atmost use N dereference operators * [ ], \* are the dereference operators for int, char, float, double * [ ], \* , -> are the dereference operators for structure, and union pointers .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Step 4 : Free from innermost pointer .. _malloc_advanced_ex_1: .. tab-set:: .. tab-item:: Example 1 : integer pointer inside structure .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * Task * Consider below code snippet and store value in memory pointed by ``ip`` .. code-block:: c struct ABC { int a; int b; int *ip; } *sp; * In this case we need two minimum mallocs since there are two pointers .. code-block:: c sp = malloc(sizeof(struct ABC)); sp->ip = malloc(sizeof(int)); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Always allocate from outermost pointer to inner most pointer .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow ``sp`` is the outer most pointer ``ip`` is the inner most pointer * Let us store some value by dereferencing .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * With respect to structure pointer there are three ways of dereferencing ``(*sp)``, ``sp->`` and ``sp[0]`` * With respect to integer pointer there are two ways of dereferencing ``*ip`` and ``ip[0]`` * In total, there are 6 ways to derefer and store / fetch values to and from memory pointed by ``ip`` .. code-block:: c (*sp).ip[0] = 65; OR .. code-block:: c *((*sp).ip) = 65; OR .. code-block:: c sp->ip[0] = 65; OR .. code-block:: c *(sp->ip) = 65; OR .. code-block:: c sp[0].ip[0] = 65; OR .. code-block:: c *(sp[0].ip) = 65; .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Note that for complete derefernce there are atmost two operators used ======================== ================================== Operator combination Description ======================== ================================== (\*sp).ip[0] \* and [ ] \*((\*sp).ip) \* and \* sp->ip[0] -> and [ ] \*(sp->ip) \* and -> sp[0].ip[0] [ ] and [ ] \*(sp[0].ip) \* and [ ] ======================== ================================== .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Since there are two pointers we can atmost use two dereference operators * More generically, we can say .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow If there are N pointers we can atmost use N dereference operators * Free the memory from innermost .. code-block:: c free(sp->ip); free(sp); * See the full program below .. code-block:: c :linenos: :emphasize-lines: 12, 14, 34, 35 #include #include struct ABC { int a; int b; int *ip; } *sp; int main(void) { sp = malloc(sizeof(struct ABC)); sp->ip = malloc(sizeof(int)); (*sp).ip[0] = 65; printf("(*sp).ip[0] = %d\n", (*sp).ip[0]); *((*sp).ip) = 65; printf("*((*sp).ip) = %d\n", *((*sp).ip)); sp->ip[0] = 65; printf("sp->ip[0] = %d\n", sp->ip[0]); *(sp->ip) = 65; printf("*(sp->ip) = %d\n",*(sp->ip) ); sp[0].ip[0] = 65; printf("sp[0].ip[0] = %d\n", sp[0].ip[0]); *(sp[0].ip) = 65; printf("*(sp[0].ip) = %d\n", *(sp[0].ip)); free(sp->ip); free(sp); return 0; } =============================================================================== ================================== Summary of Learning =============================================================================== ================================== * Allocate from outermost pointer * Free from innermost pointer * [ ], \* are the dereference operators for int, char, float, double * [ ], \* , -> are the dereference operators for structure, and union pointers * If there are N pointers we can atmost use N dereference operators =============================================================================== ================================== .. _malloc_advanced_ex_2: .. tab-set:: .. tab-item:: Example 2 : integer pointer inside nested structure : Single pointer .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * Task * Consider below code snippet and store value in memory pointed by ``ip`` .. code-block:: c struct ABC { int a; int b; int *ip; }; struct PQR { int p; int q; struct ABC *abc_ptr; } *pqr_ptr; * In this case we need three minimum mallocs since there are three pointers .. code-block:: c pqr_ptr = malloc(sizeof(struct PQR)); pqr_ptr->abc_ptr = malloc(sizeof(struct ABC)); pqr_ptr->abc_ptr->ip = malloc(sizeof(int)); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Always allocate from outermost pointer to inner most pointer .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow ``pqr_ptr`` is the outer most pointer ``abc_ptr`` is the first inner pointer ``ip`` is the second inner pointer which is also the innermost * Let us store some value by dereferencing .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * With respect to structure pointer ``pqr_ptr`` there are three ways of dereferencing ``(*)``, ``->`` and ``[0]`` * With respect to structure pointer ``abc_ptr`` there are three ways of dereferencing ``(*)``, ``->`` and ``[0]`` * With respect to integer pointer ``ip`` there are two ways of dereferencing ``*ip`` and ``ip[0]`` * In total, there are 3x3x2 = 18 ways to derefer and store / fetch values to and from memory pointed by ``ip`` * As of now let us look at one basic example .. code-block:: c *pqr_ptr->abc_ptr->ip = 65; .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Note that for complete derefernce there are atmost three operators used .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Since there are three pointers we can atmost use two dereference operators * More generically, we can say .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow If there are N pointers we can atmost use N dereference operators * Free the memory from innermost .. code-block:: c free(pqr_ptr->abc_ptr->ip); free(pqr_ptr->abc_ptr); free(pqr_ptr); * See the full program below .. code-block:: c :linenos: :emphasize-lines: 18, 20, 22, 28, 30, 32 #include #include struct ABC { int a; int b; int *ip; }; struct PQR { int p; int q; struct ABC *abc_ptr; } *pqr_ptr; int main(void) { pqr_ptr = malloc(sizeof(struct PQR)); pqr_ptr->abc_ptr = malloc(sizeof(struct ABC)); pqr_ptr->abc_ptr->ip = malloc(sizeof(int)); *pqr_ptr->abc_ptr->ip = 65; printf("*pqr_ptr->abc_ptr->ip = %d\n", *pqr_ptr->abc_ptr->ip); free(pqr_ptr->abc_ptr->ip); free(pqr_ptr->abc_ptr); free(pqr_ptr); return 0; } =============================================================================== ================================== Summary of Learning =============================================================================== ================================== * Allocate from outermost pointer * Free from innermost pointer * [ ], \* are the dereference operators for int, char, float, double * [ ], \* , -> are the dereference operators for structure, and union pointers * If there are N pointers we can atmost use N dereference operators =============================================================================== ================================== .. _malloc_advanced_ex_3: .. tab-set:: .. tab-item:: Example 3 : integer pointer inside nested structure : Double Pointer .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * Task * Consider below code snippet and store value in memory pointed by ``ip`` .. code-block:: c struct ABC { int a; int b; int *ip; }; struct PQR { int p; int q; struct ABC *abc_ptr; } **pqr_ptr; * In this case we need four minimum mallocs since there are four pointers (pqr_ptr, \*pqr_ptr, abc_ptr, ip) .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Always allocate from outermost pointer to inner most pointer .. code-block:: c pqr_ptr = malloc(sizeof(struct PQR *)); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow ``pqr_ptr`` is a double pointer and points to array of single pointers .. code-block:: c *pqr_ptr = malloc(sizeof(struct PQR )); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow ``*pqr_ptr`` is a single pointer and points to array of structure objects .. code-block:: c (**pqr_ptr).abc_ptr = malloc(sizeof(struct ABC)); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow ``(**pqr_ptr)`` is completely dereferenced. Hence it is a structure object .. code-block:: c (**pqr_ptr).abc_ptr->ip = malloc(sizeof(int)); .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Since ``(**pqr_ptr)`` is structure object, members can be accessed with . (dot) operator * Access inner most pointer ``ip`` .. code-block:: c *(**pqr_ptr).abc_ptr->ip = 65; * Free the memory from innermost .. code-block:: c free((**pqr_ptr).abc_ptr->ip); free((**pqr_ptr).abc_ptr); free(*pqr_ptr); free(pqr_ptr); * See the full program below .. code-block:: c :linenos: :emphasize-lines: 18, 20, 22, 24, 30, 32, 34, 36 #include #include struct ABC { int a; int b; int *ip; }; struct PQR { int p; int q; struct ABC *abc_ptr; } **pqr_ptr; int main(void) { pqr_ptr = malloc(sizeof(struct PQR *)); *pqr_ptr = malloc(sizeof(struct PQR )); (**pqr_ptr).abc_ptr = malloc(sizeof(struct ABC)); (**pqr_ptr).abc_ptr->ip = malloc(sizeof(int)); *(**pqr_ptr).abc_ptr->ip = 65; printf("*(**pqr_ptr).abc_ptr->ip = %d\n", *(**pqr_ptr).abc_ptr->ip); free((**pqr_ptr).abc_ptr->ip); free((**pqr_ptr).abc_ptr); free(*pqr_ptr); free(pqr_ptr); 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`