Functions and Structure Triple Pointer

In this section, you are going to learn

What are the calling conventions of structure triple pointer ?

Call by Value

Call by Reference

struct ABC ***tp;

Consider a structure triple pointer

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

struct ABC ***tp;

Let us answer few basic questions about structure triple pointer

If fun(x) is the function call, then fun(typeof(x)) is the prototype / definition

Function Call

Function Definition

Observations

fun(tp[0][0][0])

void fun(struct ABC x) {}

  • Call by Value

fun(tp[1][0][0])

void fun(struct ABC x) {}

  • Call by Value

fun(&tp[0][0][0])

void fun(struct ABC *p) {}

  • Call by Reference

fun(&tp[1][0][0])

void fun(struct ABC *p) {}

  • Call by Reference

fun(tp[0][0])

void fun(struct ABC *p) {}

  • Call by Reference

fun(tp[1][0])

void fun(struct ABC *p) {}

  • Call by Reference

fun(&tp[0][0])

void fun(struct ABC **p) {}

  • Call by Reference

fun(&tp[1][0])

void fun(struct ABC **p) {}

  • Call by Reference

fun(**tp)

void fun(struct ABC *p) {}

  • Call by Reference

fun(*(*(tp + 1) + 0))

void fun(struct ABC *p) {}

  • Call by Reference

fun(tp[0])

void fun(struct ABC **p) {}

  • Call by Reference

fun(tp[1])

void fun(struct ABC **p) {}

  • Call by Reference

fun(&tp[0])

void fun(struct ABC ***p) {}

  • Call by Reference

fun(*tp)

void fun(struct ABC **p) {}

  • Call by Reference

fun(*(tp + 1))

void fun(struct ABC **p) {}

  • Call by Reference

fun(tp)

void fun(struct ABC ***p) {}

  • Call by Reference

fun(&tp)

void fun(struct ABC ****p) {}

  • Call by Reference

Let us understand the reason behind above prototypes !

If Declaration has THREE dereference operators, and

  • Expression has THREE dereference operators * * *, and

  • Expression does not have &

  • then it is call by value

If Declaration has THREE dereference operators, and

  • Expression has THREE dereference operators * * [ ], and

  • Expression does not have &

  • then it is call by value

If Declaration has THREE dereference operators, and

  • Expression has THREE dereference operators * [ ] [ ], and

  • Expression does not have &

  • then it is call by value

If Declaration has THREE dereference operators, and

  • Expression has THREE dereference operators [] [] [], and

  • Expression does not have &

  • then it is call by value

Let us look at examples

  • Step 1 : Consider a triple dimension array created using a structure triple pointer

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

struct ABC ***tp;

tp = malloc( 2 * sizeof(struct ABC **) );

for (int i = 0; i < 2; i++)
{
        tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
        for (int j = 0; j < 3; j++)
        {
                tp[i][j] = malloc( 4 * sizeof(struct ABC) );
        }
}

Condition 1 : Declaration has THREE dereference operators [ ], [ ] and [ ]

  • Step 2 : Consider an expression tp[1][1][1]

Condition 2 : Expression has THREE dereference operators [ ], [ ] and [ ]

Note : [ ] and * are dereference operators

Condition 3 : Expression DOES NOT have & operator

Hence tp[1][1][1] is Call By Value

  • Step 1 : Consider a triple dimension array created using a structure triple pointer

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

struct ABC ***tp;

tp = malloc( 2 * sizeof(struct ABC **) );

for (int i = 0; i < 2; i++)
{
        tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
        for (int j = 0; j < 3; j++)
        {
                tp[i][j] = malloc( 4 * sizeof(struct ABC) );
        }
}

Condition 1 : Declaration has THREE dereference operators [ ], [ ] and [ ]

  • Step 2 : Consider an expression ***tp

Condition 2 : Expression has THREE dereference operators *, * and *

Note : [ ] and * are dereference operators

Condition 3 : Expression DOES NOT have & operator

Hence ***tp is Call By Value

If Declaration has THREE dereference operators, and

  • Expression has THREE dereference operators * * * OR * * [] OR * [] [] OR [] [] [] and

  • Expression has &

  • then it is call by reference

  • Example : &tp[0][0][0], &tp[1][2][3]

If Declaration has THREE dereference operators, and

  • Expression has TWO dereference operator * * OR [] [] OR * []

  • then it is call by reference

  • Example : tp[0][0]

If Declaration has THREE dereference operators, and

  • Expression has ONE dereference operators, * OR [ ]

  • then it is call by reference

  • Example : tp[0]

If Declaration has THREE dereference operators, and

  • Expression has ZERO dereference operators

  • then it is call by reference

  • Example : tp

  • Step 1 : Consider a triple dimension array created using a structure triple pointer

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

struct ABC ***tp;

tp = malloc( 2 * sizeof(struct ABC **) );

for (int i = 0; i < 2; i++)
{
        tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
        for (int j = 0; j < 3; j++)
        {
                tp[i][j] = malloc( 4 * sizeof(struct ABC) );
        }
}

Condition 1 : Declaration has THREE dereference operators [ ] [ ] and [ ]

  • Step 2 : Consider an expression &tp[1][1][1]

Condition 2 : Expression has THREE dereference operators [ ] [ ] and [ ]

Note : [ ] and * are dereference operators

Condition 3 : Expression has & operator

Hence &tp[1][1][1] is Call By Reference

  • Step 1 : Consider a triple dimension array created using a structure triple pointer

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

struct ABC ***tp;

tp = malloc( 2 * sizeof(struct ABC **) );

for (int i = 0; i < 2; i++)
{
        tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
        for (int j = 0; j < 3; j++)
        {
                tp[i][j] = malloc( 4 * sizeof(struct ABC) );
        }
}

Condition 1 : Declaration has THREE dereference operators [ ] [ ] and [ ]

  • Step 2 : Consider an expression tp[1]

Condition 2 : Expression has ONE dereference operator

Note : [ ] and * are dereference operators

Condition 3 : Expression DOES NOT have & operator

Hence tp[1] is Call By Reference

Let us look at examples of Call by Value

  • Step 1 : Consider a triple dimension array created using a structure triple pointer

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

struct ABC ***tp;

tp = malloc( 2 * sizeof(struct ABC **) );

for (int i = 0; i < 2; i++)
{
        tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
        for (int j = 0; j < 3; j++)
        {
                tp[i][j] = malloc( 4 * sizeof(struct ABC) );
        }
}
  • Step 2 : Pass tp[0][0][0], tp[1][0][0] to a function fun

fun(tp[0][0][0]);

fun(tp[1][0][0]);
  • Step 3 : Define function fun

void fun(struct ABC y)
{
        y.a = 55;
        y.b = 66;
        y.c = 77;
}
  • Step 4 : Note that it is call by Value for below reason

Condition 1 : Declaration has THREE dereference operators [ ] [ ] and [ ]

Condition 2 : Expression has THREE dereference operators [ ] [ ] and [ ]

Condition 3 : Expression DOES NOT have & operator

Means changing value of structure inside function DOES NOT affect value of structure in Caller !

  • Step 5 : Free memory after use

for (int i = 0; i < 2; i++)
{
        for (int j = 0; j < 3; j++)
        {
                free( tp[i][j] );
        }
        free( tp[i] );
}

free(tp);
  • See full program below

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

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

void fun(struct ABC y)
{
        y.a = 55;
        y.b = 66;
        y.c = 77;
}

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

        tp = malloc( 2 * sizeof(struct ABC **) );

        for (int i = 0; i < 2; i++)
        {
                tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
                for (int j = 0; j < 3; j++)
                {
                        tp[i][j] = malloc( 4 * sizeof(struct ABC) );
                }
        }

        int data = 1;

        for (int i = 0; i < 2; i++)
        {
                for (int j = 0; j < 3; j++)
                {
                        for (int k = 0; k < 4; k++)
                        {
                                tp[i][j][k].a = data++;
                                tp[i][j][k].b = data++;
                                tp[i][j][k].c = data++;
                        }
                }
        }

        printf("----- Before Call By Value -----\n");
        printf("tp[0][0][0].a = %d\n", tp[0][0][0].a );
        printf("tp[0][0][0].b = %d\n", tp[0][0][0].b );
        printf("tp[0][0][0].c = %d\n", tp[0][0][0].c );

        printf("tp[1][0][0].a = %d\n", tp[1][0][0].a );
        printf("tp[1][0][0].b = %d\n", tp[1][0][0].b );
        printf("tp[1][0][0].c = %d\n", tp[1][0][0].c );

        fun(tp[0][0][0]);
        fun(tp[1][0][0]);

        printf("----- After Call By Value -----\n");
        printf("tp[0][0][0].a = %d\n", tp[0][0][0].a );
        printf("tp[0][0][0].b = %d\n", tp[0][0][0].b );
        printf("tp[0][0][0].c = %d\n", tp[0][0][0].c );

        printf("tp[1][0][0].a = %d\n", tp[1][0][0].a );
        printf("tp[1][0][0].b = %d\n", tp[1][0][0].b );
        printf("tp[1][0][0].c = %d\n", tp[1][0][0].c );

        for (int i = 0; i < 2; i++)
        {
                for (int j = 0; j < 3; j++)
                {
                        free( tp[i][j] );
                }
                free( tp[i] );
        }

        free(tp);

        return 0;
}
  • Output is as below

----- Before Call By Value -----
tp[0][0][0].a = 1
tp[0][0][0].b = 2
tp[0][0][0].c = 3
tp[1][0][0].a = 37
tp[1][0][0].b = 38
tp[1][0][0].c = 39

----- After Call By Value -----
tp[0][0][0].a = 1
tp[0][0][0].b = 2
tp[0][0][0].c = 3
tp[1][0][0].a = 37
tp[1][0][0].b = 38
tp[1][0][0].c = 39
  • Step 1 : Consider a triple dimension array created using a structure triple pointer

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

struct ABC ***tp;

tp = malloc( 2 * sizeof(struct ABC **) );

for (int i = 0; i < 2; i++)
{
        tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
        for (int j = 0; j < 3; j++)
        {
                tp[i][j] = malloc( 4 * sizeof(struct ABC) );
        }
}
  • Step 2 : Pass ***tp, *(*(*(tp + 1) + 0) + 0) to a function fun

fun( ***tp );

fun( *(*(*(tp + 1) + 0) + 0) );
  • Step 3 : Define function fun

void fun(struct ABC y)
{
        y.a = 55;
        y.b = 66;
        y.c = 77;
}
  • Step 4 : Note that it is call by Value for below reason

Condition 1 : Declaration has THREE dereference operators [ ] [ ] and [ ]

Condition 2 : Expression has THREE dereference operators * * and *

Condition 3 : Expression DOES NOT have & operator

Means changing value of structure inside function DOES NOT affect value of structure in Caller !

  • Step 5 : Free memory after use

for (int i = 0; i < 2; i++)
{
        for (int j = 0; j < 3; j++)
        {
                free( tp[i][j] );
        }
        free( tp[i] );
}

free(tp);
  • See full program below

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

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

void fun(struct ABC y)
{
        y.a = 55;
        y.b = 66;
        y.c = 77;
}

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

        tp = malloc( 2 * sizeof(struct ABC **) );

        for (int i = 0; i < 2; i++)
        {
                tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
                for (int j = 0; j < 3; j++)
                {
                        tp[i][j] = malloc( 4 * sizeof(struct ABC) );
                }
        }

        int data = 1;

        for (int i = 0; i < 2; i++)
        {
                for (int j = 0; j < 3; j++)
                {
                        for (int k = 0; k < 4; k++)
                        {
                                tp[i][j][k].a = data++;
                                tp[i][j][k].b = data++;
                                tp[i][j][k].c = data++;
                        }
                }
        }

        printf("----- Before Call By Value -----\n");
        printf(" (***tp).a = %d\n", (***tp).a );
        printf(" (***tp).b = %d\n", (***tp).b );
        printf(" (***tp).c = %d\n", (***tp).c );

        printf(" (*(*(*(tp + 1) + 0) + 0)).a = %d\n", (*(*(*(tp + 1) + 0) + 0)).a );
        printf(" (*(*(*(tp + 1) + 0) + 0)).b = %d\n", (*(*(*(tp + 1) + 0) + 0)).b );
        printf(" (*(*(*(tp + 1) + 0) + 0)).c = %d\n", (*(*(*(tp + 1) + 0) + 0)).c );

        fun( ***tp );

        fun( *(*(*(tp + 1) + 0) + 0) );

        printf("----- After Call By Value -----\n");
        printf(" (***tp).a = %d\n", (***tp).a );
        printf(" (***tp).b = %d\n", (***tp).b );
        printf(" (***tp).c = %d\n", (***tp).c );

        printf(" (*(*(*(tp + 1) + 0) + 0)).a = %d\n", (*(*(*(tp + 1) + 0) + 0)).a );
        printf(" (*(*(*(tp + 1) + 0) + 0)).b = %d\n", (*(*(*(tp + 1) + 0) + 0)).b );
        printf(" (*(*(*(tp + 1) + 0) + 0)).c = %d\n", (*(*(*(tp + 1) + 0) + 0)).c );

        for (int i = 0; i < 2; i++)
        {
                for (int j = 0; j < 3; j++)
                {
                        free( tp[i][j] );
                }
                free( tp[i] );
        }

        free(tp);

        return 0;
}
  • Output is as below

----- Before Call By Value -----
 (***tp).a = 1
 (***tp).b = 2
 (***tp).c = 3

 (*(*(*(tp + 1) + 0) + 0)).a = 37
 (*(*(*(tp + 1) + 0) + 0)).b = 38
 (*(*(*(tp + 1) + 0) + 0)).c = 39

----- After Call By Value -----
 (***tp).a = 1
 (***tp).b = 2
 (***tp).c = 3

 (*(*(*(tp + 1) + 0) + 0)).a = 37
 (*(*(*(tp + 1) + 0) + 0)).b = 38
 (*(*(*(tp + 1) + 0) + 0)).c = 39

Let us look at examples of Call by Reference

  • Step 1 : Consider a triple dimension array created using a structure triple pointer

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

struct ABC ***tp;

tp = malloc( 2 * sizeof(struct ABC **) );

for (int i = 0; i < 2; i++)
{
        tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
        for (int j = 0; j < 3; j++)
        {
                tp[i][j] = malloc( 4 * sizeof(struct ABC) );
        }
}

There are 6 single dimension arrays in struct ABC \*\*\*tp with respect to above allocation

tp[0][0]

tp[0][1]

tp[0][2]

tp[1][0]

tp[1][1]

tp[1][2]

  • Step 2.1 : Method 1 : Pass tp[0][0], tp[1][0] to a function fun

fun( tp[0][0] );

fun( tp[1][0] );
  • Step 2.2 : Method 2 : Pass &tp[0][0][0], &tp[1][0][0] to a function fun

fun( &tp[0][0][0] );

fun( &tp[1][0][0] );
  • Step 2.3 : Method 3 : Pass **tp, *(*(tp + 1) + 0) to a function fun

fun( **tp );

fun( *(*(tp + 1) + 0) );
  • Step 3.1 : Define function fun

void fun(struct ABC *ptr)
{
}
  • Step 3.2 : Note that it is call by Reference. Means contents of single dimension array can be changed inside function fun

void fun(struct ABC *ptr)
{
        // 1. Caller has passed single pointer pointing to array of 4 structure objects
        // 2. Hence, in this function 4 structure objects can be accessed and changed

        int data = 666;

        for (int i = 0; i < 4; i++)
        {
                ptr[i].a = data++;
                ptr[i].b = data++;
                ptr[i].c = data++;
        }
}
  • Step 4 : Free memory after use

for (int i = 0; i < 2; i++)
{
        for (int j = 0; j < 3; j++)
        {
                free( tp[i][j] );
        }
        free( tp[i] );
}

free(tp);
  • See full program below

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

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

void fun(struct ABC *ptr)
{
        // 1. Caller has passed single pointer pointing to array of 4 structure objects
        // 2. Hence, in this function 4 structure objects can be accessed and changed

        int data = 666;

        for (int i = 0; i < 4; i++)
        {
                ptr[i].a = data++;
                ptr[i].b = data++;
                ptr[i].c = data++;
        }
}

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

        tp = malloc( 2 * sizeof(struct ABC **) );

        for (int i = 0; i < 2; i++)
        {
                tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
                for (int j = 0; j < 3; j++)
                {
                        tp[i][j] = malloc( 4 * sizeof(struct ABC) );
                }
        }

        int data = 1;

        for (int i = 0; i < 2; i++)
        {
                for (int j = 0; j < 3; j++)
                {
                        for (int k = 0; k < 4; k++)
                        {
                                tp[i][j][k].a = data++;
                                tp[i][j][k].b = data++;
                                tp[i][j][k].c = data++;
                        }
                }
        }

        printf("----- Before Call By Reference -----\n");
        for (int i = 0; i < 4; i++)
        {
                printf("tp[0][0][%d].a = %d\n", i, tp[0][0][i].a);
                printf("tp[0][0][%d].b = %d\n", i, tp[0][0][i].b);
                printf("tp[0][0][%d].c = %d\n", i, tp[0][0][i].c);
        }

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

        // Method 1 : Access Single dimension arrays

        fun( tp[0][0] );

        fun( tp[1][0] );

        // Method 2 : Access Single dimension arrays

        fun( &tp[0][0][0] );

        fun( &tp[1][0][0] );

        // Method 3 : Access Single dimension arrays

        fun( **tp );
        fun( *(*(tp + 1) + 0) );

        printf("----- After Call By Reference -----\n");
        for (int i = 0; i < 4; i++)
        {
                printf("tp[0][0][%d].a = %d\n", i, tp[0][0][i].a);
                printf("tp[0][0][%d].b = %d\n", i, tp[0][0][i].b);
                printf("tp[0][0][%d].c = %d\n", i, tp[0][0][i].c);
        }

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

        for (int i = 0; i < 2; i++)
        {
                for (int j = 0; j < 3; j++)
                {
                        free( tp[i][j] );
                }
                free( tp[i] );
        }

        free(tp);

        return 0;
}
  • Output is as below

----- Before Call By Reference -----
tp[0][0][0].a = 1
tp[0][0][0].b = 2
tp[0][0][0].c = 3
tp[0][0][1].a = 4
tp[0][0][1].b = 5
tp[0][0][1].c = 6
tp[0][0][2].a = 7
tp[0][0][2].b = 8
tp[0][0][2].c = 9
tp[0][0][3].a = 10
tp[0][0][3].b = 11
tp[0][0][3].c = 12
tp[1][0][0].a = 37
tp[1][0][0].b = 38
tp[1][0][0].c = 39
tp[1][0][1].a = 40
tp[1][0][1].b = 41
tp[1][0][1].c = 42
tp[1][0][2].a = 43
tp[1][0][2].b = 44
tp[1][0][2].c = 45
tp[1][0][3].a = 46
tp[1][0][3].b = 47
tp[1][0][3].c = 48

----- After Call By Reference -----
tp[0][0][0].a = 666
tp[0][0][0].b = 667
tp[0][0][0].c = 668
tp[0][0][1].a = 669
tp[0][0][1].b = 670
tp[0][0][1].c = 671
tp[0][0][2].a = 672
tp[0][0][2].b = 673
tp[0][0][2].c = 674
tp[0][0][3].a = 675
tp[0][0][3].b = 676
tp[0][0][3].c = 677
tp[1][0][0].a = 666
tp[1][0][0].b = 667
tp[1][0][0].c = 668
tp[1][0][1].a = 669
tp[1][0][1].b = 670
tp[1][0][1].c = 671
tp[1][0][2].a = 672
tp[1][0][2].b = 673
tp[1][0][2].c = 674
tp[1][0][3].a = 675
tp[1][0][3].b = 676
tp[1][0][3].c = 677
  • Step 1 : Consider a triple dimension array created using a structure triple pointer

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

struct ABC ***tp;

tp = malloc( 2 * sizeof(struct ABC **) );

for (int i = 0; i < 2; i++)
{
        tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
        for (int j = 0; j < 3; j++)
        {
                tp[i][j] = malloc( 4 * sizeof(struct ABC) );
        }
}

There are 6 single dimension arrays in above location

tp[0][0]

tp[0][1]

tp[0][2]

tp[1][0]

tp[1][1]

tp[1][2]

Address of single dimension arrays is simply

&tp[0][0]

&tp[0][1]

&tp[0][2]

&tp[1][0]

&tp[1][1]

&tp[1][2]

  • Step 2.1 : Method 1 : Pass address of single dimension arrays to a function fun

fun( &tp[0][0] );

fun( &tp[1][0] );
  • Step 2.2 : Method 2 : Pass address of single dimension arrays to a function fun

fun( tp[0] );

fun( tp[1] );
  • Step 2.3 : Method 2 : Pass address of single dimension arrays to a function fun

fun( *tp );

fun( *(tp + 1) );
  • Step 3.1 : Define the function fun

void fun(struct ABC **ptr )
{

}
  • Step 3.2 : Define the function fun to change the contents of single dimension array structure by structure

void fun(struct ABC **ptr)
{
        int data = 666;

        for (int i = 0; i < 4; i++)
        {
                (*ptr)[i].a = data++;
                (*ptr)[i].b = data++;
                (*ptr)[i].c = data++;
        }
}
  • Step 4 : Free memory after use

for (int i = 0; i < 2; i++)
{
        for (int j = 0; j < 3; j++)
        {
                free( tp[i][j] );
        }
        free( tp[i] );
}

free(tp);
  • See full program below

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

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

void fun(struct ABC **ptr)
{
        int data = 666;

        for (int i = 0; i < 4; i++)
        {
                (*ptr)[i].a = data++;
                (*ptr)[i].b = data++;
                (*ptr)[i].c = data++;
        }
}

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

        tp = malloc( 2 * sizeof(struct ABC **) );

        for (int i = 0; i < 2; i++)
        {
                tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
                for (int j = 0; j < 3; j++)
                {
                        tp[i][j] = malloc( 4 * sizeof(struct ABC) );
                }
        }

        int data = 1;

        for (int i = 0; i < 2; i++)
        {
                for (int j = 0; j < 3; j++)
                {
                        for (int k = 0; k < 4; k++)
                        {
                                tp[i][j][k].a = data++;
                                tp[i][j][k].b = data++;
                                tp[i][j][k].c = data++;
                        }
                }
        }

        printf("----- Before Call By Reference -----\n");
        for (int i = 0; i < 4; i++)
        {
                printf("tp[0][0][i].a = %d ", tp[0][0][i].a);
                printf("tp[0][0][i].b = %d ", tp[0][0][i].b);
                printf("tp[0][0][i].c = %d ", tp[0][0][i].c);
                printf("\n");
        }

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

        // Method 1 : Access Single dimension arrays

        fun( &tp[0][0] );

        fun( &tp[1][0] );

        // Method 2 : Access Single dimension arrays

        fun( tp[0] );

        fun( tp[1] );

        // Method 3 : Access Single dimension arrays

        fun( *tp );

        fun( *(tp + 1) );

        printf("----- After Call By Reference -----\n");
        for (int i = 0; i < 4; i++)
        {
                printf("tp[0][0][i].a = %d ", tp[0][0][i].a);
                printf("tp[0][0][i].b = %d ", tp[0][0][i].b);
                printf("tp[0][0][i].c = %d ", tp[0][0][i].c);
                printf("\n");
        }

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

        for (int i = 0; i < 2; i++)
        {
                for (int j = 0; j < 3; j++)
                {
                        free( tp[i][j] );
                }
                free( tp[i] );
        }

        free(tp);

        return 0;
}
  • Output is as below

----- Before Call By Reference -----
tp[0][0][i].a = 1 tp[0][0][i].b = 2 tp[0][0][i].c = 3
tp[0][0][i].a = 4 tp[0][0][i].b = 5 tp[0][0][i].c = 6
tp[0][0][i].a = 7 tp[0][0][i].b = 8 tp[0][0][i].c = 9
tp[0][0][i].a = 10 tp[0][0][i].b = 11 tp[0][0][i].c = 12

tp[1][0][i].a = 37 tp[1][0][i].b = 38 tp[1][0][i].c = 39
tp[1][0][i].a = 40 tp[1][0][i].b = 41 tp[1][0][i].c = 42
tp[1][0][i].a = 43 tp[1][0][i].b = 44 tp[1][0][i].c = 45
tp[1][0][i].a = 46 tp[1][0][i].b = 47 tp[1][0][i].c = 48

----- After Call By Reference -----
tp[0][0][i].a = 666 tp[0][0][i].b = 667 tp[0][0][i].c = 668
tp[0][0][i].a = 669 tp[0][0][i].b = 670 tp[0][0][i].c = 671
tp[0][0][i].a = 672 tp[0][0][i].b = 673 tp[0][0][i].c = 674
tp[0][0][i].a = 675 tp[0][0][i].b = 676 tp[0][0][i].c = 677

tp[1][0][i].a = 666 tp[1][0][i].b = 667 tp[1][0][i].c = 668
tp[1][0][i].a = 669 tp[1][0][i].b = 670 tp[1][0][i].c = 671
tp[1][0][i].a = 672 tp[1][0][i].b = 673 tp[1][0][i].c = 674
tp[1][0][i].a = 675 tp[1][0][i].b = 676 tp[1][0][i].c = 677
  • Step 1 : Consider a triple dimension array created using a structure triple pointer

struct ABC ***tp;

tp = malloc( 2 * sizeof(struct ABC **) );

for (int i = 0; i < 2; i++)
{
        tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
        for (int j = 0; j < 3; j++)
        {
                tp[i][j] = malloc( 4 * sizeof(struct ABC) );
        }
}
  • Step 2 : Pass Double dimension array to function fun

fun(tp[1]);
  • Step 3.1 : Define function fun

void fun(struct ABC **ptr)
{

}
  • Step 3.2 : Access and Change structures inside function fun

void fun(struct ABC **ptr)
{
        int data = 666;

        for(int i = 0; i < 3; i++)
        {
                for(int j = 0; j < 4; j++)
                {
                        ptr[i][j].a = data++;
                        ptr[i][j].a = data++;
                        ptr[i][j].a = data++;
                }
        }
}
  • Step 4 : Free memory after use

for (int i = 0; i < 2; i++)
{
        for (int j = 0; j < 3; j++)
        {
                free( tp[i][j] );
        }
        free( tp[i] );
}

free(tp);
  • Step 5 : See the full program below

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

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

void fun(struct ABC **ptr)
{
        int data = 666;

        for(int i = 0; i < 3; i++)
        {
                for(int j = 0; j < 4; j++)
                {
                        ptr[i][j].a = data++;
                        ptr[i][j].b = data++;
                        ptr[i][j].c = data++;
                }
        }
}

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

        tp = malloc( 2 * sizeof(struct ABC **) );

        for (int i = 0; i < 2; i++)
        {
                tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
                for (int j = 0; j < 3; j++)
                {
                        tp[i][j] = malloc( 4 * sizeof(struct ABC) );
                }
        }

        int data = 1;

        for (int i = 0; i < 2; i++)
        {
                for (int j = 0; j < 3; j++)
                {
                        for (int k = 0; k < 4; k++)
                        {
                                tp[i][j][k].a = data++;
                                tp[i][j][k].b = data++;
                                tp[i][j][k].c = data++;
                        }
                }
        }

        printf("----- Before Call By Reference -----\n");

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

        fun(tp[1]);

        printf("----- After Call By Reference -----\n");

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

        for (int i = 0; i < 2; i++)
        {
                for (int j = 0; j < 3; j++)
                {
                        free( tp[i][j] );
                }
                free( tp[i] );
        }

        return 0;
}
  • Step 5 : Output is as below

----- Before Call By Reference -----

tp[1][0][0].a = 37 tp[1][0][0].b = 38 tp[1][0][0].c = 39
tp[1][0][1].a = 40 tp[1][0][1].b = 41 tp[1][0][1].c = 42
tp[1][0][2].a = 43 tp[1][0][2].b = 44 tp[1][0][2].c = 45
tp[1][0][3].a = 46 tp[1][0][3].b = 47 tp[1][0][3].c = 48

tp[1][1][0].a = 49 tp[1][1][0].b = 50 tp[1][1][0].c = 51
tp[1][1][1].a = 52 tp[1][1][1].b = 53 tp[1][1][1].c = 54
tp[1][1][2].a = 55 tp[1][1][2].b = 56 tp[1][1][2].c = 57
tp[1][1][3].a = 58 tp[1][1][3].b = 59 tp[1][1][3].c = 60

tp[1][2][0].a = 61 tp[1][2][0].b = 62 tp[1][2][0].c = 63
tp[1][2][1].a = 64 tp[1][2][1].b = 65 tp[1][2][1].c = 66
tp[1][2][2].a = 67 tp[1][2][2].b = 68 tp[1][2][2].c = 69
tp[1][2][3].a = 70 tp[1][2][3].b = 71 tp[1][2][3].c = 72

----- After Call By Reference -----

tp[1][0][0].a = 666 tp[1][0][0].b = 667 tp[1][0][0].c = 668
tp[1][0][1].a = 669 tp[1][0][1].b = 670 tp[1][0][1].c = 671
tp[1][0][2].a = 672 tp[1][0][2].b = 673 tp[1][0][2].c = 674
tp[1][0][3].a = 675 tp[1][0][3].b = 676 tp[1][0][3].c = 677

tp[1][1][0].a = 678 tp[1][1][0].b = 679 tp[1][1][0].c = 680
tp[1][1][1].a = 681 tp[1][1][1].b = 682 tp[1][1][1].c = 683
tp[1][1][2].a = 684 tp[1][1][2].b = 685 tp[1][1][2].c = 686
tp[1][1][3].a = 687 tp[1][1][3].b = 688 tp[1][1][3].c = 689

tp[1][2][0].a = 690 tp[1][2][0].b = 691 tp[1][2][0].c = 692
tp[1][2][1].a = 693 tp[1][2][1].b = 694 tp[1][2][1].c = 695
tp[1][2][2].a = 696 tp[1][2][2].b = 697 tp[1][2][2].c = 698
tp[1][2][3].a = 699 tp[1][2][3].b = 700 tp[1][2][3].c = 701
  • Step 1 : Consider a triple dimension array created using a structure triple pointer

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

struct ABC ***tp;

tp = malloc( 2 * sizeof(struct ABC **) );

for (int i = 0; i < 2; i++)
{
        tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
        for (int j = 0; j < 3; j++)
        {
                tp[i][j] = malloc( 4 * sizeof(struct ABC) );
        }
}
  • Step 2 : Pass Address of Double dimension array to function fun

fun(&tp[1]);
  • Step 3.1 : Define function fun

void fun(struct ABC ***ptr)
{

}
  • Step 3.2 : Access and Change structures inside function fun

void fun(struct ABC ***ptr)
{
        int data = 666;

        for(int i = 0; i < 3; i++)
        {
                for(int j = 0; j < 4; j++)
                {
                        (*ptr)[i][j].a = data++;
                        (*ptr)[i][j].b = data++;
                        (*ptr)[i][j].c = data++;
                }
        }
}
  • Step 4 : Free memory after use

for (int i = 0; i < 2; i++)
{
        for (int j = 0; j < 3; j++)
        {
                free( tp[i][j] );
        }
        free( tp[i] );
}

free(tp);
  • Step 5 : See the full program below

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

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

void fun(struct ABC ***ptr)
{
        int data = 666;

        for(int i = 0; i < 3; i++)
        {
                for(int j = 0; j < 4; j++)
                {
                        (*ptr)[i][j].a = data++;
                        (*ptr)[i][j].b = data++;
                        (*ptr)[i][j].c = data++;
                }
        }
}

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

        tp = malloc( 2 * sizeof(struct ABC **) );

        for (int i = 0; i < 2; i++)
        {
                tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
                for (int j = 0; j < 3; j++)
                {
                        tp[i][j] = malloc( 4 * sizeof(struct ABC) );
                }
        }

        int data = 1;

        for (int i = 0; i < 2; i++)
        {
                for (int j = 0; j < 3; j++)
                {
                        for (int k = 0; k < 4; k++)
                        {
                                tp[i][j][k].a = data++;
                                tp[i][j][k].b = data++;
                                tp[i][j][k].c =  data++;
                        }
                }
        }

        printf("----- Before Call By Reference -----\n");

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

        fun(&tp[1]);

        printf("----- After Call By Reference -----\n");

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

        for (int i = 0; i < 2; i++)
        {
                for (int j = 0; j < 3; j++)
                {
                        free( tp[i][j] );
                }
                free( tp[i] );
        }

        free(tp);

        return 0;
}
  • Step 5 : Output is as below

----- Before Call By Reference -----

tp[1][0][0].a = 37 tp[1][0][0].b = 38 tp[1][0][0].c = 39
tp[1][0][1].a = 40 tp[1][0][1].b = 41 tp[1][0][1].c = 42
tp[1][0][2].a = 43 tp[1][0][2].b = 44 tp[1][0][2].c = 45
tp[1][0][3].a = 46 tp[1][0][3].b = 47 tp[1][0][3].c = 48

tp[1][1][0].a = 49 tp[1][1][0].b = 50 tp[1][1][0].c = 51
tp[1][1][1].a = 52 tp[1][1][1].b = 53 tp[1][1][1].c = 54
tp[1][1][2].a = 55 tp[1][1][2].b = 56 tp[1][1][2].c = 57
tp[1][1][3].a = 58 tp[1][1][3].b = 59 tp[1][1][3].c = 60

tp[1][2][0].a = 61 tp[1][2][0].b = 62 tp[1][2][0].c = 63
tp[1][2][1].a = 64 tp[1][2][1].b = 65 tp[1][2][1].c = 66
tp[1][2][2].a = 67 tp[1][2][2].b = 68 tp[1][2][2].c = 69
tp[1][2][3].a = 70 tp[1][2][3].b = 71 tp[1][2][3].c = 72

----- After Call By Reference -----

tp[1][0][0].a = 666 tp[1][0][0].b = 667 tp[1][0][0].c = 668
tp[1][0][1].a = 669 tp[1][0][1].b = 670 tp[1][0][1].c = 671
tp[1][0][2].a = 672 tp[1][0][2].b = 673 tp[1][0][2].c = 674
tp[1][0][3].a = 675 tp[1][0][3].b = 676 tp[1][0][3].c = 677

tp[1][1][0].a = 678 tp[1][1][0].b = 679 tp[1][1][0].c = 680
tp[1][1][1].a = 681 tp[1][1][1].b = 682 tp[1][1][1].c = 683
tp[1][1][2].a = 684 tp[1][1][2].b = 685 tp[1][1][2].c = 686
tp[1][1][3].a = 687 tp[1][1][3].b = 688 tp[1][1][3].c = 689

tp[1][2][0].a = 690 tp[1][2][0].b = 691 tp[1][2][0].c = 692
tp[1][2][1].a = 693 tp[1][2][1].b = 694 tp[1][2][1].c = 695
tp[1][2][2].a = 696 tp[1][2][2].b = 697 tp[1][2][2].c = 698
tp[1][2][3].a = 699 tp[1][2][3].b = 700 tp[1][2][3].c = 701
  • Step 1 : Consider a triple dimension array created using a structure triple pointer

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

struct ABC ***tp;

tp = malloc( 2 * sizeof(struct ABC **) );

for (int i = 0; i < 2; i++)
{
        tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
        for (int j = 0; j < 3; j++)
        {
                tp[i][j] = malloc( 4 * sizeof(struct ABC) );
        }
}
  • Step 2 : Pass Address of Triple Dimension array to a function

fun(&tp);
  • Step 3.1 : Define function fun

void fun(struct ABC ****ptr )
{

}
  • Step 3.2 : Access and change individual structures inside function fun

int data = 666;

for(int i = 0; i < 2; i++)
{
        for(int j = 0; j < 3; j++)
        {
                for(int k = 0; k < 4; k++)
                {
                        (*ptr)[i][j][k].a = data++;
                }
        }
}
  • Step 4 : Free memory after use

for (int i = 0; i < 2; i++)
{
        for (int j = 0; j < 3; j++)
        {
                free( tp[i][j] );
        }
        free( tp[i] );
}

free(tp);
  • See full program below

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

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

void fun(struct ABC ****ptr)
{
        int data = 666;

        for(int i = 0; i < 2; i++)
        {
                for(int j = 0; j < 3; j++)
                {
                        for(int k = 0; k < 4; k++)
                        {
                                (*ptr)[i][j][k].a = data++;
                                (*ptr)[i][j][k].b = data++;
                                (*ptr)[i][j][k].c = data++;
                        }
                }
        }
}

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

        tp = malloc( 2 * sizeof(struct ABC **) );

        for (int i = 0; i < 2; i++)
        {
                tp[i] = malloc( 3 * sizeof(sizeof(struct ABC *)) );
                for (int j = 0; j < 3; j++)
                {
                        tp[i][j] = malloc( 4 * sizeof(struct ABC) );
                }
        }

        int data = 1;

        for (int i = 0; i < 2; i++)
        {
                for (int j = 0; j < 3; j++)
                {
                        for (int k = 0; k < 4; k++)
                        {
                                tp[i][j][k].a = data++;
                                tp[i][j][k].b = data++;
                                tp[i][j][k].c = data++;
                        }
                }
        }

        printf("----- Before Call By Reference -----\n");
        for(int i = 0; i < 2; i++)
        {
                for(int j = 0; j < 3; j++)
                {
                        for(int k = 0; k < 4; k++)
                        {
                                printf("tp[%d][%d][%d].a = %d ", i, j, k, tp[i][j][k].a );
                                printf("tp[%d][%d][%d].b = %d ", i, j, k, tp[i][j][k].b );
                                printf("tp[%d][%d][%d].c = %d ", i, j, k, tp[i][j][k].c );
                                printf("\n");
                        }
                        printf("\n");
                }
                printf("\n");
        }

        fun(&tp);

        printf("----- After Call By Reference -----\n");
        for(int i = 0; i < 2; i++)
        {
                for(int j = 0; j < 3; j++)
                {
                        for(int k = 0; k < 4; k++)
                        {
                                printf("tp[%d][%d][%d].a = %d ", i, j, k, tp[i][j][k].a );
                                printf("tp[%d][%d][%d].b = %d ", i, j, k, tp[i][j][k].b );
                                printf("tp[%d][%d][%d].c = %d ", i, j, k, tp[i][j][k].c );
                                printf("\n");
                        }
                        printf("\n");
                }
                printf("\n");
        }

        for (int i = 0; i < 2; i++)
        {
                for (int j = 0; j < 3; j++)
                {
                        free( tp[i][j] );
                }
                free( tp[i] );
        }


        free(tp);

        return 0;
}
  • Output is as below

----- Before Call By Reference -----

tp[0][0][0].a = 1 tp[0][0][0].b = 2 tp[0][0][0].c = 3
tp[0][0][1].a = 4 tp[0][0][1].b = 5 tp[0][0][1].c = 6
tp[0][0][2].a = 7 tp[0][0][2].b = 8 tp[0][0][2].c = 9
tp[0][0][3].a = 10 tp[0][0][3].b = 11 tp[0][0][3].c = 12

tp[0][1][0].a = 13 tp[0][1][0].b = 14 tp[0][1][0].c = 15
tp[0][1][1].a = 16 tp[0][1][1].b = 17 tp[0][1][1].c = 18
tp[0][1][2].a = 19 tp[0][1][2].b = 20 tp[0][1][2].c = 21
tp[0][1][3].a = 22 tp[0][1][3].b = 23 tp[0][1][3].c = 24

tp[0][2][0].a = 25 tp[0][2][0].b = 26 tp[0][2][0].c = 27
tp[0][2][1].a = 28 tp[0][2][1].b = 29 tp[0][2][1].c = 30
tp[0][2][2].a = 31 tp[0][2][2].b = 32 tp[0][2][2].c = 33
tp[0][2][3].a = 34 tp[0][2][3].b = 35 tp[0][2][3].c = 36


tp[1][0][0].a = 37 tp[1][0][0].b = 38 tp[1][0][0].c = 39
tp[1][0][1].a = 40 tp[1][0][1].b = 41 tp[1][0][1].c = 42
tp[1][0][2].a = 43 tp[1][0][2].b = 44 tp[1][0][2].c = 45
tp[1][0][3].a = 46 tp[1][0][3].b = 47 tp[1][0][3].c = 48

tp[1][1][0].a = 49 tp[1][1][0].b = 50 tp[1][1][0].c = 51
tp[1][1][1].a = 52 tp[1][1][1].b = 53 tp[1][1][1].c = 54
tp[1][1][2].a = 55 tp[1][1][2].b = 56 tp[1][1][2].c = 57
tp[1][1][3].a = 58 tp[1][1][3].b = 59 tp[1][1][3].c = 60

tp[1][2][0].a = 61 tp[1][2][0].b = 62 tp[1][2][0].c = 63
tp[1][2][1].a = 64 tp[1][2][1].b = 65 tp[1][2][1].c = 66
tp[1][2][2].a = 67 tp[1][2][2].b = 68 tp[1][2][2].c = 69
tp[1][2][3].a = 70 tp[1][2][3].b = 71 tp[1][2][3].c = 72


----- After Call By Reference -----

tp[0][0][0].a = 666 tp[0][0][0].b = 667 tp[0][0][0].c = 668
tp[0][0][1].a = 669 tp[0][0][1].b = 670 tp[0][0][1].c = 671
tp[0][0][2].a = 672 tp[0][0][2].b = 673 tp[0][0][2].c = 674
tp[0][0][3].a = 675 tp[0][0][3].b = 676 tp[0][0][3].c = 677

tp[0][1][0].a = 678 tp[0][1][0].b = 679 tp[0][1][0].c = 680
tp[0][1][1].a = 681 tp[0][1][1].b = 682 tp[0][1][1].c = 683
tp[0][1][2].a = 684 tp[0][1][2].b = 685 tp[0][1][2].c = 686
tp[0][1][3].a = 687 tp[0][1][3].b = 688 tp[0][1][3].c = 689

tp[0][2][0].a = 690 tp[0][2][0].b = 691 tp[0][2][0].c = 692
tp[0][2][1].a = 693 tp[0][2][1].b = 694 tp[0][2][1].c = 695
tp[0][2][2].a = 696 tp[0][2][2].b = 697 tp[0][2][2].c = 698
tp[0][2][3].a = 699 tp[0][2][3].b = 700 tp[0][2][3].c = 701


tp[1][0][0].a = 702 tp[1][0][0].b = 703 tp[1][0][0].c = 704
tp[1][0][1].a = 705 tp[1][0][1].b = 706 tp[1][0][1].c = 707
tp[1][0][2].a = 708 tp[1][0][2].b = 709 tp[1][0][2].c = 710
tp[1][0][3].a = 711 tp[1][0][3].b = 712 tp[1][0][3].c = 713

tp[1][1][0].a = 714 tp[1][1][0].b = 715 tp[1][1][0].c = 716
tp[1][1][1].a = 717 tp[1][1][1].b = 718 tp[1][1][1].c = 719
tp[1][1][2].a = 720 tp[1][1][2].b = 721 tp[1][1][2].c = 722
tp[1][1][3].a = 723 tp[1][1][3].b = 724 tp[1][1][3].c = 725

tp[1][2][0].a = 726 tp[1][2][0].b = 727 tp[1][2][0].c = 728
tp[1][2][1].a = 729 tp[1][2][1].b = 730 tp[1][2][1].c = 731
tp[1][2][2].a = 732 tp[1][2][2].b = 733 tp[1][2][2].c = 734
tp[1][2][3].a = 735 tp[1][2][3].b = 736 tp[1][2][3].c = 737