Basics of Structure Double Pointers

In this section, you are going to learn

  • Step 1 : Define a structure

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

struct ABC x = { .a = 1, .b = 2, .c = 3 };
  • Step 2 : Define a Single Pointer

struct ABC *sp = &x;

OR

struct ABC *sp;

sp = &x;
  • Step 3 : Define a Double Pointer

struct ABC **dp = &sp;

OR

struct ABC **dp;

dp = &sp;
  • Step 4 : Access user data (in this case structure) using single pointer sp

printf("sp->a = %d\n", sp->a);
printf("sp->b = %d\n", sp->b);
printf("sp->c = %d\n", sp->c);
  • Step 5 : Access user data (in this case structure) using double pointer dp

printf("(*dp)->a = %d\n", (*dp)->a);
printf("(*dp)->b = %d\n", (*dp)->b);
printf("(*dp)->c = %d\n", (*dp)->c);
  • See full program below

#include <stdio.h>

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

int main(void)
{
        struct ABC x = { .a = 1, .b = 2, .c = 3 };

        struct ABC *sp;
        sp = &x;

        struct ABC **dp;
        dp = &sp;

        printf("sp->a = %d\n", sp->a);
        printf("sp->b = %d\n", sp->b);
        printf("sp->c = %d\n", sp->c);

        printf("(*dp)->a = %d\n", (*dp)->a);
        printf("(*dp)->b = %d\n", (*dp)->b);
        printf("(*dp)->c = %d\n", (*dp)->c);

        return 0;
}
  • Output is as below

sp->a = 1
sp->b = 2
sp->c = 3

(*dp)->a = 1
(*dp)->b = 2
(*dp)->c = 3
  • Step 1 : Define a single dimension array of structures

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

struct ABC arr[3] = {
        { .a = 1, .b = 2, .c = 3 },
        { .a = 10, .b = 20, .c = 30 },
        { .a = 100, .b = 200, .c = 300 },
};
  • Step 2 : Define a single pointer

struct ABC *sp = arr;

OR

struct ABC *sp;

sp = arr;

OR

struct ABC *sp;

sp = &arr[0];
  • Step 3 : Define a double pointer

struct ABC **dp = &sp;

OR

struct ABC **dp;

dp = &sp;
  • Step 4 : Access user data (in this case array of structures) using single pointer variable arr

for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++)
{
        printf("arr[%d].a = %d\n", i, arr[i].a);
        printf("arr[%d].b = %d\n", i, arr[i].b);
        printf("arr[%d].c = %d\n", i, arr[i].c);
}
  • Step 5 : Access user data (in this case array of structures) using single pointer variable sp

for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++)
{
        printf("sp[%d].a = %d\n", i, sp[i].a);
        printf("sp[%d].b = %d\n", i, sp[i].b);
        printf("sp[%d].c = %d\n", i, sp[i].c);
}
  • Step 6 : Access user data (in this case array of structures) using double pointer variable dp

for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++)
{
        printf("(*dp)[%d].a = %d\n", i, (*dp)[i].a);
        printf("(*dp)[%d].b = %d\n", i, (*dp)[i].b);
        printf("(*dp)[%d].c = %d\n", i, (*dp)[i].c);
}

Note *dp should be called as single pointer because of below equations

  • dp = &sp;

  • *dp = sp;

  • See full program below

#include <stdio.h>

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

int main(void)
{
        struct ABC arr[3] = {
                { .a = 1, .b = 2, .c = 3 },
                { .a = 10, .b = 20, .c = 30 },
                { .a = 100, .b = 200, .c = 300 },
        };

        struct ABC *sp;
        sp = arr;

        struct ABC **dp;
        dp = &sp;

        // Access user data (in this case array of structures) using single pointer variable ``arr``
        for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++)
        {
                printf("arr[%d].a = %d\n", i, arr[i].a);
                printf("arr[%d].b = %d\n", i, arr[i].b);
                printf("arr[%d].c = %d\n", i, arr[i].c);
        }

        // Access user data (in this case array of structures) using single pointer variable ``sp``
        for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++)
        {
                printf("sp[%d].a = %d\n", i, sp[i].a);
                printf("sp[%d].b = %d\n", i, sp[i].b);
                printf("sp[%d].c = %d\n", i, sp[i].c);
        }

        // Access user data (in this case array of structures) using double pointer variable ``dp``
        for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++)
        {
                printf("(*dp)[%d].a = %d\n", i, (*dp)[i].a);
                printf("(*dp)[%d].b = %d\n", i, (*dp)[i].b);
                printf("(*dp)[%d].c = %d\n", i, (*dp)[i].c);
        }

        return 0;
}
  • Output is as below

arr[0].a = 1
arr[0].b = 2
arr[0].c = 3
arr[1].a = 10
arr[1].b = 20
arr[1].c = 30
arr[2].a = 100
arr[2].b = 200
arr[2].c = 300

sp[0].a = 1
sp[0].b = 2
sp[0].c = 3
sp[1].a = 10
sp[1].b = 20
sp[1].c = 30
sp[2].a = 100
sp[2].b = 200
sp[2].c = 300

(*dp)[0].a = 1
(*dp)[0].b = 2
(*dp)[0].c = 3
(*dp)[1].a = 10
(*dp)[1].b = 20
(*dp)[1].c = 30
(*dp)[2].a = 100
(*dp)[2].b = 200
(*dp)[2].c = 300
  • Step 1 : Define a single pointer

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

struct ABC *sp;
  • Step 2 : Allocate heap memory to single pointer

sp = malloc(3 * sizeof(struct ABC));
  • Step 3 : Copy User data to heap memory

sp[0].a = 1; sp[0].b = 2; sp[0].c = 3;
sp[1].a = 4; sp[1].b = 5; sp[1].c = 6;
sp[2].a = 7; sp[2].b = 8; sp[2].c = 9;
  • Step 4 : Define a double pointer

struct ABC **dp;
dp = &sp;
  • Step 5 : Access User data using single pointer variable sp

for (int i = 0 ; i < 3; i++)
{
        printf("sp[%d].a = %d\n", i, sp[i].a);
        printf("sp[%d].b = %d\n", i, sp[i].b);
        printf("sp[%d].c = %d\n", i, sp[i].c);
}
  • Step 6 : Access User data using double pointer variable dp

for (int i = 0 ; i < 3; i++)
{
        printf("(*dp)[%d].a = %d\n", i, (*dp)[i].a);
        printf("(*dp)[%d].b = %d\n", i, (*dp)[i].b);
        printf("(*dp)[%d].c = %d\n", i, (*dp)[i].c);
}
  • Step 7 : Free heap memory after use

free(sp);

OR

free(*dp);
  • See full program below

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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

int main(void)
{
        struct ABC *sp;
        sp = malloc(3 * sizeof(struct ABC));

        memset(sp, 0, 3 * sizeof(struct ABC));

        sp[0].a = 1; sp[0].b = 2; sp[0].c = 3;
        sp[1].a = 4; sp[1].b = 5; sp[1].c = 6;
        sp[2].a = 7; sp[2].b = 8; sp[2].c = 9;

        struct ABC **dp;
        dp = &sp;

        // Access user data (in this case array of structures) using single pointer variable ``sp``
        for (int i = 0 ; i < 3; i++)
        {
                printf("sp[%d].a = %d\n", i, sp[i].a);
                printf("sp[%d].b = %d\n", i, sp[i].b);
                printf("sp[%d].c = %d\n", i, sp[i].c);
        }

        // Access user data (in this case array of structures) using double pointer variable ``dp``
        for (int i = 0 ; i < 3; i++)
        {
                printf("(*dp)[%d].a = %d\n", i, (*dp)[i].a);
                printf("(*dp)[%d].b = %d\n", i, (*dp)[i].b);
                printf("(*dp)[%d].c = %d\n", i, (*dp)[i].c);
        }

        free(sp);

        return 0;
}
  • Output is as below

sp[0].a = 1
sp[0].b = 2
sp[0].c = 3
sp[1].a = 4
sp[1].b = 5
sp[1].c = 6
sp[2].a = 7
sp[2].b = 8
sp[2].c = 9

(*dp)[0].a = 1
(*dp)[0].b = 2
(*dp)[0].c = 3
(*dp)[1].a = 4
(*dp)[1].b = 5
(*dp)[1].c = 6
(*dp)[2].a = 7
(*dp)[2].b = 8
(*dp)[2].c = 9
  • Step 1 : Define a double pointer

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

struct ABC **dp;
  • Step 2 : Allocate memory to a double pointer

dp = malloc(sizeof(struct ABC *));
  • Step 3 : Allocate memory to a single pointer

*dp = malloc(sizeof(struct ABC));
  • Step 4 : Store user data

(**dp).a = 1;
(**dp).b = 2;
(**dp).c = 3;
  • Step 5 : Read user data

printf("(**dp).a = %d\n", (**dp).a);
printf("(**dp).b = %d\n", (**dp).b);
printf("(**dp).c = %d\n", (**dp).c);
  • Step 6 : Free memory in opposite flow of allocation

free(*dp);

free(dp);
  • See full program below

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

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

int main(void)
{
        struct ABC **dp;

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

        (**dp).a = 1;
        (**dp).b = 2;
        (**dp).c = 3;

        printf("(**dp).a = %d\n", (**dp).a);
        printf("(**dp).b = %d\n", (**dp).b);
        printf("(**dp).c = %d\n", (**dp).c);

        free(*dp);

        free(dp);

        return 0;
}
  • Output is as below

(**dp).a = 1
(**dp).b = 2
(**dp).c = 3
  • Step 1 : Define a double pointer

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

struct ABC **dp;
  • Step 2 : Allocate memory to a double pointer

dp = malloc(sizeof(struct ABC *));
  • Step 3 : Allocate memory to a single pointer

*dp = malloc(3 * sizeof(struct ABC));
  • Step 4 : Copy User data to heap

(*dp)[0].a = 1;
(*dp)[0].b = 2;
(*dp)[0].c = 3;
(*dp)[1].a = 4;
(*dp)[1].b = 5;
(*dp)[1].c = 6;
(*dp)[2].a = 7;
(*dp)[2].b = 8;
(*dp)[2].c = 9;
  • Step 5 : Read user data from heap

for (int i = 0; i < 3; i++) {
        printf("(*dp)[%d].a = %d\n", i, (*dp)[i].a);
        printf("(*dp)[%d].b = %d\n", i, (*dp)[i].b);
        printf("(*dp)[%d].c = %d\n", i, (*dp)[i].c);
}
  • Step 6 : Free memory in opposite flow of allocation

free(*dp);

free(dp);
  • See full program below

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

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

int main(void)
{
        struct ABC **dp;

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

        *dp = malloc(3 * sizeof(struct ABC));

        memset(*dp, 0, 3 * sizeof(struct ABC) );

        (*dp)[0].a = 1;
        (*dp)[0].b = 2;
        (*dp)[0].c = 3;

        (*dp)[1].a = 4;
        (*dp)[1].b = 5;
        (*dp)[1].c = 6;

        (*dp)[2].a = 7;
        (*dp)[2].b = 8;
        (*dp)[2].c = 9;

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

        free(*dp);

        free(dp);

        return 0;
}
  • See full program below

(*dp)[0].a = 1
(*dp)[0].b = 2
(*dp)[0].c = 3

(*dp)[1].a = 4
(*dp)[1].b = 5
(*dp)[1].c = 6

(*dp)[2].a = 7
(*dp)[2].b = 8
(*dp)[2].c = 9
  • Step 1 : Define a double pointer

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

struct ABC **dp;
  • Step 2 : Pass double pointer by reference

fun(&dp);
  • Step 3 : Allocate memory inside function fun

void fun(struct ABC ***dp_r)
{
        *dp_r = malloc(2 * sizeof(struct ABC *));
        (*dp_r)[0] = malloc(3 * sizeof(struct ABC));
        (*dp_r)[1] = malloc(3 * sizeof(struct ABC));
}
  • Step 4 : Use single pointers dp[0], dp[1] in caller to store user data

dp[0][0].a = 1;
dp[0][0].b = 2;
dp[0][0].c = 3;

dp[0][1].a = 4;
dp[0][1].b = 5;
dp[0][1].c = 6;

dp[0][2].a = 7;
dp[0][2].b = 8;
dp[0][2].c = 9;

dp[1][0].a = 10;
dp[1][0].b = 11;
dp[1][0].c = 12;

dp[1][1].a = 13;
dp[1][1].b = 14;
dp[1][1].c = 15;

dp[1][2].a = 16;
dp[1][2].b = 17;
dp[1][2].c = 18;
  • Step 5 : Use single pointers dp[0], dp[1] in caller to access user data

for (int i = 0; i < 2; i++)
{
        for (int j = 0; j < 3; j++)
        {
                printf("dp[%d][%d].a = %d\n", i, j, dp[i][j].a);
                printf("dp[%d][%d].b = %d\n", i, j, dp[i][j].b);
                printf("dp[%d][%d].c = %d\n", i, j, dp[i][j].c);
        }
                printf("\n");
}
  • Step 6 : Free 2 arrays of structures after use

free(dp[0]);
free(dp[1]);
  • Step 7 : Free 2 Single pointers after use

free(dp);
  • See full program below

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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

void fun(struct ABC ***dp_r)
{
        *dp_r = malloc(2 * sizeof(struct ABC *));
        (*dp_r)[0] = malloc(3 * sizeof(struct ABC));
        (*dp_r)[1] = malloc(3 * sizeof(struct ABC));
}

int main(void)
{
        struct ABC **dp;

        fun(&dp);

        dp[0][0].a = 1;
        dp[0][0].b = 2;
        dp[0][0].c = 3;

        dp[0][1].a = 4;
        dp[0][1].b = 5;
        dp[0][1].c = 6;

        dp[0][2].a = 7;
        dp[0][2].b = 8;
        dp[0][2].c = 9;

        dp[1][0].a = 10;
        dp[1][0].b = 11;
        dp[1][0].c = 12;

        dp[1][1].a = 13;
        dp[1][1].b = 14;
        dp[1][1].c = 15;

        dp[1][2].a = 16;
        dp[1][2].b = 17;
        dp[1][2].c = 18;

        for (int i = 0; i < 2; i++)
        {
                for (int j = 0; j < 3; j++)
                {
                        printf("dp[%d][%d].a = %d\n", i, j, dp[i][j].a);
                        printf("dp[%d][%d].b = %d\n", i, j, dp[i][j].b);
                        printf("dp[%d][%d].c = %d\n", i, j, dp[i][j].c);
                }
                printf("\n");
        }

        free(dp[0]);
        free(dp[1]);

        free(dp);

        return 0;
}
  • See full program below

dp[0][0].a = 1
dp[0][0].b = 2
dp[0][0].c = 3
dp[0][1].a = 4
dp[0][1].b = 5
dp[0][1].c = 6
dp[0][2].a = 7
dp[0][2].b = 8
dp[0][2].c = 9

dp[1][0].a = 10
dp[1][0].b = 11
dp[1][0].c = 12
dp[1][1].a = 13
dp[1][1].b = 14
dp[1][1].c = 15
dp[1][2].a = 16
dp[1][2].b = 17
dp[1][2].c = 18