Basics of Structure Triple Pointers
In this section, you are going to learn
How to use Triple Pointers ?
Basics of Triple Pointers
1 Triple Pointer 1 Double Pointer, 1 Single Pointer : Simple variables
1 Triple Pointer, 1 Double Pointer, 1 Single Pointer : With Single pointer pointing to arrays
1 Triple Pointer, 1 Double Pointer, 1 Single Pointer : With Single pointer heap allocation
1 Triple Pointer, 1 Double Pointer : With two heap allocations : Create 1x1 array
1 Triple Pointer, 1 Double Pointer : With two heap allocations : Create 1x10 array
1 Triple Pointer, 1 Double Pointer : Pointing to array of single pointers : Dynamic
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 : Define a Triple pointer
struct ABC ***tp = &dp;
OR
struct ABC ***tp;
tp = &dp;
Step 5 : Access user data (in this case structure) using single pointer
printf("sp->a = %d\n", sp->a);
printf("sp->b = %d\n", sp->b);
printf("sp->c = %d\n", sp->c);
Step 6 : Access user data (in this case structure) using double pointer
printf("(*dp)->a = %d\n", (*dp)->a);
printf("(*dp)->b = %d\n", (*dp)->b);
printf("(*dp)->c = %d\n", (*dp)->c);
Step 7 : Access user data (in this case structure) using triple pointer
printf("(**tp)->a = %d\n", (**tp)->a);
printf("(**tp)->b = %d\n", (**tp)->b);
printf("(**tp)->c = %d\n", (**tp)->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;
struct ABC ***tp;
tp = &dp;
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);
printf("(**tp)->a = %d\n", (**tp)->a);
printf("(**tp)->b = %d\n", (**tp)->b);
printf("(**tp)->c = %d\n", (**tp)->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
(**tp)->a = 1
(**tp)->b = 2
(**tp)->c = 3
Summary of Naming conventions
Consider
struct ABC ***tp;
then
tp is a triple pointer
*tp is a double pointer
**tp is a single pointer
***tp is user data
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 : Define a Triple pointer
struct ABC ***tp = &dp;
OR
struct ABC ***tp;
tp = &dp;
Step 5 : 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);
}
Step 7 : Access user data (in this case array of structures) using triple pointer variable
tp
for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++)
{
printf("(**tp)[%d].a = %d\n", i, (**tp)[i].a);
printf("(**tp)[%d].b = %d\n", i, (**tp)[i].b);
printf("(**tp)[%d].c = %d\n", i, (**tp)[i].c);
}
Note *dp
should be called as single pointer because of below equations
dp = &sp;
*dp = sp;
Note **tp
should be called as single pointer because of below equations
tp = &dp;
*tp = dp;
*tp = &sp;
**tp = 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;
struct ABC ***tp;
tp = &dp;
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);
}
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);
}
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);
}
for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++)
{
printf("(**tp)[%d].a = %d\n", i, (**tp)[i].a);
printf("(**tp)[%d].b = %d\n", i, (**tp)[i].b);
printf("(**tp)[%d].c = %d\n", i, (**tp)[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
(**tp)[0].a = 1
(**tp)[0].b = 2
(**tp)[0].c = 3
(**tp)[1].a = 10
(**tp)[1].b = 20
(**tp)[1].c = 30
(**tp)[2].a = 100
(**tp)[2].b = 200
(**tp)[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 = 10;
sp[1].b = 20;
sp[1].c = 30;
sp[2].a = 100;
sp[2].b = 200;
sp[2].c = 300;
Step 4 : Define a double pointer
struct ABC **dp;
dp = &sp;
Step 5 : Define a Triple pointer
struct ABC ***tp = &dp;
OR
struct ABC ***tp;
tp = &dp;
Step 6 : Access User data 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 7 : Access User data 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);
}
Step 8 : Access User data using triple pointer variable
tp
for (int i = 0 ; i < sizeof(arr)/sizeof(arr[0]); i++)
{
printf("(**tp)[%d].a = %d\n", i, (**tp)[i].a);
printf("(**tp)[%d].b = %d\n", i, (**tp)[i].b);
printf("(**tp)[%d].c = %d\n", i, (**tp)[i].c);
}
Step 9 : Free memory after usage
free(sp);
OR
free(*dp);
OR
free(**tp);
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));
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;
struct ABC **dp;
dp = &sp;
struct ABC ***tp;
tp = &dp;
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);
}
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);
}
for (int i = 0 ; i < 3; i++)
{
printf("(**tp)[%d].a = %d\n", i, (**tp)[i].a);
printf("(**tp)[%d].b = %d\n", i, (**tp)[i].b);
printf("(**tp)[%d].c = %d\n", i, (**tp)[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 = 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
(**tp)[0].a = 1
(**tp)[0].b = 2
(**tp)[0].c = 3
(**tp)[1].a = 10
(**tp)[1].b = 20
(**tp)[1].c = 30
(**tp)[2].a = 100
(**tp)[2].b = 200
(**tp)[2].c = 300
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 : Define a Triple pointer
struct ABC ***tp = &dp;
OR
struct ABC ***tp;
tp = &dp;
Step 6 : Read user data using
dp
printf("(*dp)->a = %d\n", (*dp)->a);
printf("(*dp)->b = %d\n", (*dp)->b);
printf("(*dp)->c = %d\n", (*dp)->c);
Step 7 : Read user data using
tp
printf("(**tp)->a = %d\n", (**tp)->a);
printf("(**tp)->b = %d\n", (**tp)->b);
printf("(**tp)->c = %d\n", (**tp)->c);
Step 8 : Free memory in opposite flow of allocation
free(*dp);
free(dp);
OR
free(**tp);
free(*tp);
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);
struct ABC ***tp;
tp = &dp;
printf("(**tp)->a = %d\n", (**tp)->a);
printf("(**tp)->b = %d\n", (**tp)->b);
printf("(**tp)->c = %d\n", (**tp)->c);
free(*dp); // or free(**tp);
free(dp); // or free(*tp);
return 0;
}
Output is as below
(*dp)->a = 1
(*dp)->b = 2
(*dp)->c = 3
(**tp)->a = 1
(**tp)->b = 2
(**tp)->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 = 10;
(*dp)[1].b = 20;
(*dp)[1].c = 30;
(*dp)[2].a = 100;
(*dp)[2].b = 200;
(*dp)[2].c = 300;
Step 5 : Define a Triple pointer
struct ABC ***tp = &dp;
OR
struct ABC ***tp;
tp = &dp;
Step 6 : Read user data from heap using
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 : Read user data from heap using
tp
for (int i = 0; i < 3; i++) {
printf("(**tp)[%d].a = %d\n", i, (**tp)[i].a );
printf("(**tp)[%d].b = %d\n", i, (**tp)[i].b );
printf("(**tp)[%d].c = %d\n", i, (**tp)[i].c );
}
Step 6 : Free memory in opposite flow of allocation
free(*dp);
free(dp);
OR
free(**tp);
free(*tp);
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));
(*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;
struct ABC ***tp;
tp = &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 );
}
for (int i = 0; i < 3; i++) {
printf("(**tp)[%d].a = %d\n", i, (**tp)[i].a );
printf("(**tp)[%d].b = %d\n", i, (**tp)[i].b );
printf("(**tp)[%d].c = %d\n", i, (**tp)[i].c );
}
free(*dp); // or free(**tp);
free(dp); // or free(*tp);
return 0;
}
Output is as below
(*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
(**tp)[0].a = 1
(**tp)[0].b = 2
(**tp)[0].c = 3
(**tp)[1].a = 10
(**tp)[1].b = 20
(**tp)[1].c = 30
(**tp)[2].a = 100
(**tp)[2].b = 200
(**tp)[2].c = 300
Step 1 : Define a double pointer
struct ABC {
int a;
int b;
int c;
};
struct ABC **dp;
Step 2 : Allocate heap memory : Create 2 single pointers
dp[0]
,dp[1]
dp = malloc(2 * sizeof(struct ABC *));
Step 3 : Allocate heap memory : Create 2 single dimension structure arrays of size 3 structures each
dp[0] = malloc(3 * sizeof(struct ABC));
dp[1] = malloc(3 * sizeof(struct ABC));
Step 4 : 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 : Define a Triple pointer
struct ABC ***tp = &dp;
OR
struct ABC ***tp;
tp = &dp;
Step 6 : Access user data using
dp
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 );
}
}
Step 7 : Access user data using
tp
for (int i = 0 ; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
printf("(*tp)[%d][%d].a = %d\n", i, j, (*tp)[i][j].a );
printf("(*tp)[%d][%d].b = %d\n", i, j, (*tp)[i][j].b );
printf("(*tp)[%d][%d].c = %d\n", i, j, (*tp)[i][j].c );
}
}
Step 6 : Free 2 structure arrays
free(dp[0]);
free(dp[1]);
OR
free((*tp)[0]);
free((*tp)[1]);
Step 7 : Free 2 single pointers
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 **dp;
dp = malloc(2 * sizeof(struct ABC *));
dp[0] = malloc(3 * sizeof(struct ABC));
dp[1] = malloc(3 * sizeof(struct ABC));
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;
struct ABC ***tp;
tp = &dp;
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 );
}
}
for (int i = 0 ; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
printf("(*tp)[%d][%d].a = %d\n", i, j, (*tp)[i][j].a );
printf("(*tp)[%d][%d].b = %d\n", i, j, (*tp)[i][j].b );
printf("(*tp)[%d][%d].c = %d\n", i, j, (*tp)[i][j].c );
}
}
free(dp[0]);
free(dp[1]);
free(dp);
return 0;
}
Output as is 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
(*tp)[0][0].a = 1
(*tp)[0][0].b = 2
(*tp)[0][0].c = 3
(*tp)[0][1].a = 4
(*tp)[0][1].b = 5
(*tp)[0][1].c = 6
(*tp)[0][2].a = 7
(*tp)[0][2].b = 8
(*tp)[0][2].c = 9
(*tp)[1][0].a = 10
(*tp)[1][0].b = 11
(*tp)[1][0].c = 12
(*tp)[1][1].a = 13
(*tp)[1][1].b = 14
(*tp)[1][1].c = 15
(*tp)[1][2].a = 16
(*tp)[1][2].b = 17
(*tp)[1][2].c = 18
Current Module
Previous Module
Next Module
Other Modules