Question: 3-d array with different size of row and column

i am making a three-d array the problem i am facing is i want to create multiple 3-d array however with varying size of row and column so the first matrix size could be 0-2-2 while next matrix could be say 1-1-3 so on..
kindly do not suggest making a large matrix that could have value of all the row and columns.
i personally have tried using structure to create the code, i have defined 2-d array( for row and column) in the structure and then stored it in variable e[1].array(2-d), i have used for loop to continuously change value of row and column in array based on user input, the problem i am facing is every time the for loop changes value to next the code over writes itself hence previous values  of array can not be called so if for first matrix the size of row and column was 2-2 and next is 1-3 so e[1].x[2][2] have some value then for second loops e[1].x[1][3] the dimensions of x have been re-defined hence i could not call x[2][2].
kindly suggest ways i could store 3-d array with different size of row and column for each matrix.
 int main()
 {
 int matrix;
 printf("ENTER NUMBER OF MATRICES\n");
 scanf("%d`", &matrix);
 int row, column;


for (int m = 0; m < matrix; m++) {
    printf("ENTER NUMBER OF ROWS IN %d MATRICE\n", m + 1);
    scanf("%d", &row);
    printf("ENTER NUMBER OF column IN %d MATICE\n", m + 1);
    scanf("%d", &column);
     struct x {
  int f[row][column];
};
    struct x k[m];
    int g = 1;

    printf("ENTER ALL ELEMENT LEFT TO RIGHT\n");
    for (int j = 0; j < row; j++) {
        
        for (int u = 0; u < column; u++) {
            
            printf("%d)\n", g);
            scanf("%d", &k[m].f[j][u]);
            g = g + 1;
        }
    }
    for (int s = 0; s < row; s++) {
        printf("|");
        for (int l = 0; l < column; l++) {
             
            printf("%d", k[m].f[s][l]);
            if (l < column - 1) {
                printf("  ");
                
            }
        }
        printf("|\n");
        
    }
    printf("%d", k[0].f[0][0]); // error here calling over written 
 value
 }
  return 0;

expectation:
 ENTER NUMBER OF MATRICES
 2
 ENTER NUMBER OF ROWS IN 1 MATRICE
 2
 ENTER NUMBER OF column IN 1 MATICE
 2
 ENTER ALL ELEMENT LEFT TO RIGHT  
 1)
 1
 2)
 2
 3)
 3      4
 4)
 4
 |1  2|
 |3  4|
 ENTER NUMBER OF ROWS IN 2 MATRICE
 1
 ENTER NUMBER OF column IN 2 MATICE
 3
 ENTER ALL ELEMENT LEFT TO RIGHT
 1)
 5
 2)
 6
 3)
 7
 |5  6  7|
 1 // error here in output



Answer:
Since each matrix may be a different size, you should manage each matrix separately and record its dimensions separately. The code below shows how to use a structure type to do that.
Common C implementations support variable length arrays, so you use this to make addressing the matrix elements simpler. The program below shows how to use a pointer to a variable length array to point to the rows of a matrix. The memory address is recorded in the structure using void *, because we cannot have a variably modified type in the structure, but a separate variable is declared where it is needed, and it is set to the start of memory for the matrix.
In the absence of using variable length arrays, you would have to address the elements using manual arithmetic calculations into a linear array.
#include <stdio.h>
#include <stdlib.h>


int main(void)
{
    // Read the number of matrices.
    int NMatrices;
    printf("Enter the number of matrices:  ");
    if (1 != scanf("%d", &NMatrices))
    {
        fprintf(stderr, "Error, scanf for number of matrices failed.\n");
        exit(EXIT_FAILURE);
    }
    if (NMatrices < 0)
    {
        fprintf(stderr, "Error, number of matrices is negative.\n");
        exit(EXIT_FAILURE);
    }

    // Define a type to manage a matrix.
    struct MatrixInformation
    {
        void *Memory;        // Memory for the matrix.
        int NRows, NColumns; // Number of rows and number of columns.
    };

    // Allocate memory to manage NMatrices matrices.
    struct MatrixInformation *Matrices = malloc(NMatrices * sizeof *Matrices);
    if (!Matrices)
    {
        fprintf(stderr, "Error, failed to allocate memory.\n");
        exit(EXIT_FAILURE);
    }

    // Read each matrix.
    for (int m = 0; m < NMatrices; ++m)
    {
        // Read the number of rows and the number of columns of this matrix.
        int NRows, NColumns;
        printf("Enter the number of rows in matrix %d:  ", m+1);
        if (1 != scanf("%d", &NRows))
        {
            fprintf(stderr, "Error, scanf for number of rows failed.\n");
            exit(EXIT_FAILURE);
        }
        if (NRows <= 0)
        {
            fprintf(stderr, "Error, number of rows is not positive.\n");
            exit(EXIT_FAILURE);
        }
        printf("Enter the number of columns in matrix %d:  ", m+1);
        if (1 != scanf("%d", &NColumns))
        {
            fprintf(stderr, "Error, scanf for number of columns failed.\n");
            exit(EXIT_FAILURE);
        }
        if (NColumns <= 0)
        {
            fprintf(stderr, "Error, number of columns is not positive.\n");
            exit(EXIT_FAILURE);
        }

        // Create a temporary pointer for the matrix and allocate memory.
        int (*Matrix)[NColumns] = malloc(NRows * sizeof *Matrix);
        if (!Matrix)
        {
            fprintf(stderr, "Error, failed to allocate memory.\n");
            exit(EXIT_FAILURE);
        }

        // Save the numbers of rows and columns and the memory address.
        Matrices[m].NRows = NRows;
        Matrices[m].NColumns = NColumns;
        Matrices[m].Memory = Matrix;

        // Get the values for the matrix elements.
        for (int r = 0; r < NRows; ++r)
            for (int c = 0; c < NColumns; ++c)
            {
                printf("Enter the element [%d, %d]:  ", r+1, c+1);
                if (1 != scanf("%d", &Matrix[r][c]))
                {
                    fprintf(stderr, "Error, scanf for element failed.\n");
                    exit(EXIT_FAILURE);
                }
            }
    }

    // Print each matrix.
    for (int m = 0; m < NMatrices; ++m)
    {
        printf("Matrix %d:\n", m+1);

        // Get the numbers of rows and columns and the memory address.
        int NRows = Matrices[m].NRows;
        int NColumns = Matrices[m].NColumns;
        int (*Matrix)[NColumns] = Matrices[m].Memory;

        // Print each row.
        for (int r = 0; r < NRows; ++r)
        {
            // Start each row with a delimiter and no spaces.
            printf("|%d", Matrix[r][0]);

            // Print each element with two spaces for separation.
            for (int c = 1; c < NColumns; ++c)
                printf("  %d", Matrix[r][c]);

            // Finish each row with a delimiter and a new-line character.
            printf("|\n");
        }
    }

    // Free the memory of each matrix.
    for (int m = 0; m < NMatrices; ++m)
        free(Matrices[m].Memory);

    // Free the memory for the array of structures about the matrices.
    free(Matrices);
}