Malloc struct Double pointer

  • In this section, you are going to learn

How to allocate memory using malloc ?

How to allocate memory using calloc ?

How to allocate memory using realloc ?

  • Key point to remember

    • Double pointer points to array of single pointers

    • Single pointer points to array of structures

  • Example is arr[2][3]

    • Where there are 2 rows and 3 columns

  • Now let us take a look at real time examples

  • Step 1 : Include stdlib.h

#include <stdlib.h>
  • Step 2 : Define Double pointer

struct ABC {
        int a;
        int b;
        int c;
};

struct ABC **ptr;
  • Step 3 : Create One single pointer

ptr = malloc( sizeof(struct ABC *) );

Allocates 8 Bytes of memory in heap

  • ptr points to array of single pointers

  • In this case, array has one single pointer

  • sizeof(ptr) is 8 Bytes

  • Step 4 : Create One single structure

*ptr = malloc( sizeof(struct ABC) );

OR

ptr[0] = malloc( sizeof(struct ABC) );

Allocates 12 Bytes of memory in heap

  • Step 5 : Assign value to structure

(*ptr)->a = 65;

OR

(*ptr)[0].a = 65;

OR

ptr[0][0].a = 65;
  • Step 6 : Print the value

printf("(*ptr)->a = %d\n", (*ptr)->a);

OR

printf("(*ptr)[0].a = %d\n", (*ptr)[0].a);

OR

printf("ptr[0][0].a = %d\n", ptr[0][0].a);
  • Step 7 : Free after use

free(*ptr);
free(ptr);

Free in the opposite order of allocation

  • See the full program below

 1#include <stdio.h>
 2
 3// Step 1 : Include stdlib.h
 4#include <stdlib.h>
 5
 6int main(void)
 7{
 8        // Step 2 : Define Double pointer
 9        struct ABC {
10                int a;
11                int b;
12                int c;
13        };
14
15        struct ABC **ptr;
16
17        // Step 3 : Create One single pointer
18        ptr = malloc( sizeof(struct ABC *) );
19
20        // Step 4 : Create One single structure
21        *ptr = malloc( sizeof(struct ABC) );
22
23        // Step 5 : Assign value to structure
24        (*ptr)->a = 65;
25
26        // Step 6 : Print the value
27        printf("(*ptr)->a = %d\n", (*ptr)->a);
28
29        (*ptr)[0].a = 66;
30        printf("(*ptr)[0].a = %d\n", (*ptr)[0].a);
31
32        ptr[0][0].a = 67;
33        printf("ptr[0][0].a = %d\n", ptr[0][0].a);
34
35        // Step 7 : Free after use
36        free(*ptr);
37        free(ptr);
38
39        return 0;
40}

Statement

Description

ptr = malloc( sizeof(struct ABC *) )

  • ptr points to array of single pointers

*ptr = malloc( sizeof(struct ABC) )

  • *ptr points to array of structures

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)

  • 12 Bytes

  • Fully dereferenced

  • Hence takes the size of actual type

(*ptr)->a

  • Method 1 : Access member

(*ptr)[0].a

  • Method 2 : Access member

ptr[0][0].a

  • Method 3 : Access member

  • Step 1 : Include stdlib.h

#include <stdlib.h>
  • Step 2 : Define Double pointer

struct ABC {
        int a;
        int b;
        int c;
};

struct ABC **ptr;
  • Step 3 : Create One single pointer

ptr = malloc( sizeof(struct ABC *) );

Allocates 8 Bytes of memory in heap

  • ptr points to array of single pointers

  • In this case, array has one single pointer

  • sizeof(ptr) is 8 Bytes

  • Step 4 : Create Ten Structure Objects from (*ptr)[0] … (*ptr)[9]

*ptr = malloc( 10 * sizeof(struct ABC) );

OR

ptr[0] = malloc( 10 * sizeof(struct ABC) );

Allocates 120 Bytes of memory in heap

  • Step 5 : Assign value to structure

for (int i = 0; i < 10; i++)
{
        (*ptr)[i].a = ++val;
}

OR

for (int i = 0; i < 10; i++)
{
        ptr[0][i].a = ++val;
}

OR

for (int i = 0; i < 10; i++)
{
        ( *( *( ptr ) + i ) ).a = ++val;
}

OR

for (int i = 0; i < 10; i++)
{
        (*ptr + i)->a = ++val;
}
  • Step 6 : Print the value

for (int i = 0; i < 10; i++)
{
        printf("(*ptr)[%d].a = %d\n", i, (*ptr)[i].a);
}

OR

for (int i = 0; i < 10; i++)
{
        printf("ptr[0][%d].a = %d\n", i, ptr[0][i].a);
}

OR

for (int i = 0; i < 10; i++)
{
        printf("( *( *( ptr ) + %d ) ).a  = %d\n", i, ( *( *( ptr ) + i ) ).a );
}

OR

for (int i = 0; i < 10; i++)
{
        printf("(*ptr + %d)->a  = %d\n", i, (*ptr + i)->a );
}
  • Step 7 : Free after use

free(*ptr);
free(ptr);

Free in the opposite order of allocation

  • See the full program below

 1#include <stdio.h>
 2
 3// Step 1 : Include stdlib.h
 4#include <stdlib.h>
 5
 6int main(void)
 7{
 8        // Step 2 : Define Double pointer
 9        struct ABC {
10                int a;
11                int b;
12                int c;
13        };
14
15        struct ABC **ptr;
16        int val = 0;
17
18        // Step 3 : Create One single pointer
19        ptr = malloc( sizeof(struct ABC *) );
20
21        // Step 4 : Create Ten Structure Objects from (*ptr)[0] ... (*ptr)[9]
22        *ptr = malloc( 10 * sizeof(struct ABC) );
23
24        // Step 5.1 : Assign value to structure objects
25        for (int i = 0; i < 10; i++)
26        {
27                (*ptr)[i].a = ++val;
28        }
29
30        // Step 6.1 : Print the value
31        for (int i = 0; i < 10; i++)
32        {
33                printf("(*ptr)[%d].a = %d\n", i, (*ptr)[i].a);
34        }
35
36        // Step 5.2 : Assign value to structure objects
37        for (int i = 0; i < 10; i++)
38        {
39                ptr[0][i].a = ++val;
40        }
41
42        // Step 6.2 : Print the value
43        for (int i = 0; i < 10; i++)
44        {
45                printf("ptr[0][%d].a = %d\n", i, ptr[0][i].a);
46        }
47
48
49        // Step 5.3 : Assign value to structure objects
50        for (int i = 0; i < 10; i++)
51        {
52                ( *( *( ptr ) + i ) ).a = ++val;
53        }
54
55        // Step 6.3 : Print the value
56        for (int i = 0; i < 10; i++)
57        {
58                printf("( *( *( ptr ) + %d ) ).a  = %d\n", i, ( *( *( ptr ) + i ) ).a );
59        }
60
61        // Step 5.4 : Assign value to structure objects
62        for (int i = 0; i < 10; i++)
63        {
64                (*ptr + i)->a = ++val;
65        }
66
67        // Step 6.4 : Print the value
68        for (int i = 0; i < 10; i++)
69        {
70                printf("(*ptr + %d)->a  = %d\n", i, (*ptr + i)->a );
71        }
72
73        // Step 7 : Free after use
74        free(*ptr);
75        free(ptr);
76
77        return 0;
78}

Statement

Description

ptr = malloc( sizeof(struct ABC *) )

  • ptr points to array of single pointers

*ptr = malloc( 10 * sizeof(struct ABC) )

  • *ptr points to array of 10 structures

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)

  • 12 Bytes

  • Fully dereferenced

  • Hence takes the size of actual type

( *ptr )[ i ].a

  • Method 1 : Access member

ptr[ 0 ][ i ].a

  • Method 2 : Access member

( *( *( ptr ) + i ) ).a

  • Method 3 : Access member

( *ptr + i )->a

  • Method 4 : Access member

  • Step 1 : Include stdlib.h

#include <stdlib.h>
  • Step 2 : Define Double pointer

struct ABC {
int a;
int b;
int c;
};

struct ABC **ptr;
  • Step 3 : Create Ten single pointers from ptr[0] to ptr[9]

ptr = malloc( 10 * sizeof(struct ABC *) );
  • Step 4 : Create One Structure Object from ptr[0][0] to ptr[9][0]

for (int i = 0; i < 10; i++)
{
        ptr[i] = malloc( sizeof(struct ABC) );
}
  • Step 5 : Assign value to structure objects

for (int i = 0; i < 10; i++)
{
        ptr[i][0].a = ++val;
}

OR

for (int i = 0; i < 10; i++)
{
        ptr[i]->a = ++val;
}

OR

for (int i = 0; i < 10; i++)
{
        (*(ptr + i))->a = ++val;
}

OR

for (int i = 0; i < 10; i++)
{
        ( *( *( ptr + i ) ) ).a = ++val;
}
  • Step 6 : Print the value

for (int i = 0; i < 10; i++)
{
        printf("ptr[%d][0].a = %d\n", i, ptr[i][0].a);
}

OR

for (int i = 0; i < 10; i++)
{
        printf("ptr[%d]->a = %d\n", i, ptr[i]->a);
}

OR

for (int i = 0; i < 10; i++)
{
        printf("(*(ptr + %d))->a = %d\n", i, (*(ptr + i))->a);
}

OR

for (int i = 0; i < 10; i++)
{
        printf("( *( *( ptr + %d ) ) ).a  = %d\n", i, ( *( *( ptr + i ) ) ).a );
}
  • Step 7 : Free after use

for (int i = 0; i < 10; i++)
{
        free(ptr[i]);
}

free(ptr);
  • See the full program below

 1#include <stdio.h>
 2
 3// Step 1 : Include stdlib.h
 4#include <stdlib.h>
 5
 6int main(void)
 7{
 8        // Step 2 : Define Double pointer
 9        struct ABC {
10                int a;
11                int b;
12                int c;
13        };
14
15        struct ABC **ptr;
16        int val = 0;
17
18        // Step 3 : Create Ten single pointers from ptr[0] to ptr[9]
19        ptr = malloc( 10 * sizeof(struct ABC *) );
20
21        // Step 4 : Create One Structure Object from ptr[0][0] to ptr[9][0]
22        for (int i = 0; i < 10; i++)
23        {
24                ptr[i] = malloc( sizeof(struct ABC) );
25        }
26
27        // Step 5.1 : Assign value to structure objects
28        for (int i = 0; i < 10; i++)
29        {
30                ptr[i][0].a = ++val;
31        }
32
33        // Step 6.1 : Print the value
34        for (int i = 0; i < 10; i++)
35        {
36                printf("ptr[%d][0].a = %d\n", i, ptr[i][0].a);
37        }
38
39        // Step 5.2 : Assign value to structure objects
40        for (int i = 0; i < 10; i++)
41        {
42                ptr[i]->a = ++val;
43        }
44
45        // Step 6.2 : Print the value
46        for (int i = 0; i < 10; i++)
47        {
48                printf("ptr[%d]->a = %d\n", i, ptr[i]->a);
49        }
50
51        // Step 5.3 : Assign value to structure objects
52        for (int i = 0; i < 10; i++)
53        {
54                (*(ptr + i))->a = ++val;
55        }
56
57        // Step 6.3 : Print the value
58        for (int i = 0; i < 10; i++)
59        {
60                printf("(*(ptr + %d))->a = %d\n", i, (*(ptr + i))->a);
61        }
62
63        // Step 5.4 : Assign value to structure objects
64        for (int i = 0; i < 10; i++)
65        {
66                ( *( *( ptr + i ) ) ).a = ++val;
67        }
68
69        // Step 6.4 : Print the value
70        for (int i = 0; i < 10; i++)
71        {
72                printf("( *( *( ptr + %d ) ) ).a  = %d\n", i, ( *( *( ptr + i ) ) ).a );
73        }
74
75        // Step 7 : Free after use
76        for (int i = 0; i < 10; i++)
77        {
78                free(ptr[i]);
79        }
80
81        free(ptr);
82
83        return 0;
84}
  • Step 1 : Include stdlib.h

#include <stdlib.h>
  • Step 2 : Define Double pointer

struct ABC {
        int a;
        int b;
        int c;
};

struct ABC **ptr;
  • Step 3 : Create Ten single pointers from ptr[0] to ptr[9]

ptr = malloc( 10 * sizeof(struct ABC *) );
  • Step 4 : Create 100 Structure Objects from ptr[0][0] to ptr[9][9]

for (int i = 0; i < 10; i++)
{
        ptr[i] = malloc( 10 * sizeof(struct ABC) );
}
  • Step 5 : Assign value to structure objects

for (int i = 0; i < 10; i++)
{
        for (int j = 0; j < 10; j++)
        {
                ptr[i][j].a = ++val;
        }
}
  • Step 6 : Print the value

for (int i = 0; i < 10; i++)
{
        for (int j = 0; j < 10; j++)
        {
                printf("ptr[%d][%d].a = %d\n", i, j, ptr[i][j].a);
        }
}
  • Step 7 : Free after use

for (int i = 0; i < 10; i++)
{
        free(ptr[i]);
}
free(ptr);
  • See the full program below

#include <stdio.h>

// Step 1 : Include stdlib.h
#include <stdlib.h>

int main(void)
{
        // Step 2 : Define Double pointer
        struct ABC {
                int a;
                int b;
                int c;
        };

        struct ABC **ptr;
        int val = 0;

        // Step 3 : Create Ten single pointers from ptr[0] to ptr[9]
        ptr = malloc( 10 * sizeof(struct ABC *) );

        // Step 4 : Create 100 Structure Objects from ptr[0][0] to ptr[9][9]
        for (int i = 0; i < 10; i++)
        {
                ptr[i] = malloc( 10 * sizeof(struct ABC) );
        }

        // Step 5 : Assign value to structure objects
        for (int i = 0; i < 10; i++)
        {
                for (int j = 0; j < 10; j++)
                {
                        ptr[i][j].a = ++val;
                }
        }

        // Step 6 : Print the value
        for (int i = 0; i < 10; i++)
        {
                for (int j = 0; j < 10; j++)
                {
                        printf("ptr[%d][%d].a = %d\n", i, j, ptr[i][j].a);
                }
        }

        // Step 7 : Free after use
        for (int i = 0; i < 10; i++)
        {
                free(ptr[i]);
        }

        free(ptr);

        return 0;
}
  • Step 1 : Include stdlib.h

#include <stdlib.h>
  • Step 2 : Define an allocation function

void get_memory(struct ABC **dp)
{
        // *dp is equal to sp in caller
        *dp = malloc(10 * sizeof(struct ABC));

        memset(*dp, 0, 10 * sizeof(struct ABC));
}
  • Step 3: Define a single pointer

struct ABC {
        int a;
        int b;
        int c;
};

struct ABC *sp;
  • Step 4 : Pass single pointer sp by reference

get_memory(&sp);
  • Step 5.1 : sp is now pointing to array of 10 structures. Access members and assign

for (int i = 0; i < 10; i++)
{
        sp[i].a = ++val;
}

OR

for (int i = 0; i < 10; i++)
{
        (sp + i)->a = ++val;
}

OR

for (int i = 0; i < 10; i++)
{
        (*(sp + i)).a = ++val;
}
  • Step 5.2 : Print the values

for (int i = 0; i < 10; i++)
{
        printf("sp[%d].a = %d\n", i, sp[i].a);
}

OR

for (int i = 0; i < 10; i++)
{
        printf("(sp + %d)->a = %d\n", i, (sp + i)->a);
}

OR

for (int i = 0; i < 10; i++)
{
        printf("(*(sp + %d)).a = %d\n", i, (*(sp + i)).a);
}
  • Step 6 : Free the memory

free(sp);
  • See full program below

 1#include <stdio.h>
 2#include <string.h>
 3
 4// Step 1 : Include stdlib.h
 5#include <stdlib.h>
 6
 7struct ABC {
 8        int a;
 9        int b;
10        int c;
11};
12
13// Step 2 : Define an allocation function
14void get_memory(struct ABC **dp)
15{
16        // *dp is equal to sp in caller
17        *dp = malloc(10 * sizeof(struct ABC));
18
19        memset(*dp, 0, 10 * sizeof(struct ABC));
20}
21
22int main(void)
23{
24        // Step 3: Define a single pointer
25        struct ABC *sp;
26        int val = 0;
27
28        // Step 4 : Pass single pointer "sp" by reference
29        get_memory(&sp);
30
31        // Step 5.1 : "sp" is now pointing to array of 10 structures from sp[0] to sp[9]
32        for (int i = 0; i < 10; i++)
33        {
34                sp[i].a = ++val;
35        }
36
37        // Step 5.2 : Print the values
38        for (int i = 0; i < 10; i++)
39        {
40                printf("sp[%d].a = %d\n", i, sp[i].a);
41        }
42
43        for (int i = 0; i < 10; i++)
44        {
45                (sp + i)->a = ++val;
46        }
47
48        for (int i = 0; i < 10; i++)
49        {
50                printf("(sp + %d)->a = %d\n", i, (sp + i)->a);
51        }
52
53        for (int i = 0; i < 10; i++)
54        {
55                (*(sp + i)).a = ++val;
56        }
57
58        for (int i = 0; i < 10; i++)
59        {
60                printf("(*(sp + %d)).a = %d\n", i, (*(sp + i)).a);
61        }
62
63        // Step 6 : Free the memory
64        free(sp);
65
66        return 0;
67}
  • Step 1 : Include stdlib.h

#include <stdlib.h>
  • Step 2 : Define an allocation function

void get_memory(struct ABC ***tp)
{
}
  • Step 2.1 : Create Ten Single Pointers from tp[0] … tp[9]

void get_memory(struct ABC ***tp)
{
        *tp = malloc( 10 * sizeof(struct ABC *) );
}
  • 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

void get_memory(struct ***tp)
{
        *tp = malloc( 10 * sizeof(struct ABC *) );

        for (int i = 0; i < 10; i++)
        {
                (*tp)[i] = malloc( 10 * sizeof(struct ABC) );
        }
}
  • *tp[] is a single pointer and will point to array of structures

  • Step 3: Define a single pointer

struct ABC {
        int a;
        int b;
        int c;
};

struct ABC **dp;
  • Step 4 : Pass double pointer “dp” by reference

get_memory(&dp);
  • Step 5 : Assign values to array of structures from dp[0][0] to dp[9][9]

for (int i = 0; i < 10; i++)
{
        for (int j = 0; j < 10; j++)
        {
                dp[i][j].a = ++val;
        }
}
  • Step 6 : Print the structures from dp[0][0] to dp[9][9]

for (int i = 0; i < 10; i++)
{
        for (int j = 0; j < 10; j++)
        {
                printf("dp[%d][%d].a = %d\n", i, j, dp[i][j].a);
        }
}
  • Step 7 : Free after use

for (int i = 0; i < 10; i++)
{
        free(dp[i]);
}

free(dp);
  • See the full program below

 1#include <stdio.h>
 2#include <string.h>
 3
 4// Step 1 : Include stdlib.h
 5#include <stdlib.h>
 6
 7struct ABC {
 8        int a;
 9        int b;
10        int c;
11};
12
13// Step 2 : Define an allocation function
14void get_memory(struct ABC ***tp)
15{
16        // Step 2.1 : Create Ten Single Pointers from tp[0] ... tp[9]
17        *tp = malloc( 10 * sizeof(struct ABC *) );
18
19        // Step 2.2 : Create Ten Characters in every Row
20        for (int i = 0; i < 10; i++)
21        {
22               (*tp)[i] = malloc( 10 * sizeof(struct ABC) );
23        }
24}
25
26int main(void)
27{
28        // Step 3: Define a single pointer
29        struct ABC **dp;
30        int val = 0;
31
32        // Step 4 : Pass double pointer "dp" by reference
33        get_memory(&dp);
34
35        // Step 5 : Assign strings to array of structures
36        for (int i = 0; i < 10; i++)
37        {
38                for (int j = 0; j < 10; j++)
39                {
40                        dp[i][j].a = ++val;
41                }
42        }
43
44        // Step 6 : Print the strings
45        for (int i = 0; i < 10; i++)
46        {
47                for (int j = 0; j < 10; j++)
48                {
49                        printf("dp[%d][%d].a = %d\n", i, j, dp[i][j].a);
50                }
51        }
52
53        // Step 7 : Free after use
54        for (int i = 0; i < 10; i++)
55        {
56                free(dp[i]);
57        }
58
59        free(dp);
60
61        return 0;
62}