Malloc Advanced Combinations

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

struct ABC **ptr;

Hence, we require minimum of two mallocs before we access members inside structure

Step 2 : Allocate from outermost pointer

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

Step 4 : Free from innermost pointer

  • Task

    • Consider below code snippet and store value in memory pointed by ip

struct ABC {
        int a;
        int b;
        int *ip;
} *sp;
  • In this case we need two minimum mallocs since there are two pointers

sp = malloc(sizeof(struct ABC));

sp->ip = malloc(sizeof(int));

Always allocate from outermost pointer to inner most pointer

sp is the outer most pointer

ip is the inner most pointer

  • Let us store some value by dereferencing

  • 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

(*sp).ip[0] = 65;

OR

*((*sp).ip) = 65;

OR

sp->ip[0] = 65;

OR

*(sp->ip) = 65;

OR

sp[0].ip[0] = 65;

OR

*(sp[0].ip) = 65;

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 [ ]

Since there are two pointers we can atmost use two dereference operators

  • More generically, we can say

If there are N pointers we can atmost use N dereference operators

  • Free the memory from innermost

free(sp->ip);
free(sp);
  • See the full program below

 1#include <stdio.h>
 2#include <stdlib.h>
 3
 4struct ABC {
 5        int a;
 6        int b;
 7        int *ip;
 8} *sp;
 9
10int main(void)
11{
12        sp = malloc(sizeof(struct ABC));
13
14        sp->ip = malloc(sizeof(int));
15
16        (*sp).ip[0] = 65;
17        printf("(*sp).ip[0] = %d\n", (*sp).ip[0]);
18
19        *((*sp).ip) = 65;
20        printf("*((*sp).ip) = %d\n", *((*sp).ip));
21
22        sp->ip[0] = 65;
23        printf("sp->ip[0] = %d\n", sp->ip[0]);
24
25        *(sp->ip) = 65;
26        printf("*(sp->ip) = %d\n",*(sp->ip) );
27
28        sp[0].ip[0] = 65;
29        printf("sp[0].ip[0] = %d\n", sp[0].ip[0]);
30
31        *(sp[0].ip) = 65;
32        printf("*(sp[0].ip) = %d\n", *(sp[0].ip));
33
34        free(sp->ip);
35        free(sp);
36
37        return 0;
38}

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

  • Task

    • Consider below code snippet and store value in memory pointed by ip

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

pqr_ptr = malloc(sizeof(struct PQR));

pqr_ptr->abc_ptr = malloc(sizeof(struct ABC));

pqr_ptr->abc_ptr->ip = malloc(sizeof(int));

Always allocate from outermost pointer to inner most pointer

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

  • 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

*pqr_ptr->abc_ptr->ip = 65;

Note that for complete derefernce there are atmost three operators used

Since there are three pointers we can atmost use two dereference operators

  • More generically, we can say

If there are N pointers we can atmost use N dereference operators

  • Free the memory from innermost

free(pqr_ptr->abc_ptr->ip);
free(pqr_ptr->abc_ptr);
free(pqr_ptr);
  • See the full program below

 1#include <stdio.h>
 2#include <stdlib.h>
 3
 4struct ABC {
 5        int a;
 6        int b;
 7        int *ip;
 8};
 9
10struct PQR {
11        int p;
12        int q;
13        struct ABC *abc_ptr;
14} *pqr_ptr;
15
16int main(void)
17{
18        pqr_ptr = malloc(sizeof(struct PQR));
19
20        pqr_ptr->abc_ptr = malloc(sizeof(struct ABC));
21
22        pqr_ptr->abc_ptr->ip = malloc(sizeof(int));
23
24        *pqr_ptr->abc_ptr->ip = 65;
25
26        printf("*pqr_ptr->abc_ptr->ip = %d\n", *pqr_ptr->abc_ptr->ip);
27
28        free(pqr_ptr->abc_ptr->ip);
29
30        free(pqr_ptr->abc_ptr);
31
32        free(pqr_ptr);
33
34        return 0;
35}

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

  • Task

    • Consider below code snippet and store value in memory pointed by ip

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)

Always allocate from outermost pointer to inner most pointer

pqr_ptr = malloc(sizeof(struct PQR *));

pqr_ptr is a double pointer and points to array of single pointers

*pqr_ptr = malloc(sizeof(struct PQR ));

*pqr_ptr is a single pointer and points to array of structure objects

(**pqr_ptr).abc_ptr = malloc(sizeof(struct ABC));

(**pqr_ptr) is completely dereferenced. Hence it is a structure object

(**pqr_ptr).abc_ptr->ip = malloc(sizeof(int));

Since (**pqr_ptr) is structure object, members can be accessed with . (dot) operator

  • Access inner most pointer ip

*(**pqr_ptr).abc_ptr->ip = 65;
  • Free the memory from innermost

free((**pqr_ptr).abc_ptr->ip);

free((**pqr_ptr).abc_ptr);

free(*pqr_ptr);

free(pqr_ptr);
  • See the full program below

 1#include <stdio.h>
 2#include <stdlib.h>
 3
 4struct ABC {
 5        int a;
 6        int b;
 7        int *ip;
 8};
 9
10struct PQR {
11        int p;
12        int q;
13        struct ABC *abc_ptr;
14} **pqr_ptr;
15
16int main(void)
17{
18        pqr_ptr = malloc(sizeof(struct PQR *));
19
20        *pqr_ptr = malloc(sizeof(struct PQR ));
21
22        (**pqr_ptr).abc_ptr = malloc(sizeof(struct ABC));
23
24        (**pqr_ptr).abc_ptr->ip = malloc(sizeof(int));
25
26        *(**pqr_ptr).abc_ptr->ip = 65;
27
28        printf("*(**pqr_ptr).abc_ptr->ip = %d\n", *(**pqr_ptr).abc_ptr->ip);
29
30        free((**pqr_ptr).abc_ptr->ip);
31
32        free((**pqr_ptr).abc_ptr);
33
34        free(*pqr_ptr);
35
36        free(pqr_ptr);
37
38        return 0;
39}