arrayscmultidimensional-arraysize

3d array with different size of row and column


Problem: I need to create several 3D arrays with different shapes—for example, one of size 0×2×2, another of size 1×1×3, and so on—and manage them despite their varying dimensions.

Previous Approaches: I tried using a struct with a 2D array member (x) and storing it in e[1]. Inside a loop, I update the row and column sizes based on user input, but each iteration redefines x’s dimensions and overwrites the previous data. For example, after filling x[2][2], resizing to x[1][3] destroys the original x[2][2] values, so I can’t access them later. Kindly suggest ways I could store 3-d array with different size of row and column for each matrix.

Code:

 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

Solution

  • Idea:

    Store each matrix (and its dimensions) in its own struct. Since C structs can’t include variable-length array types directly, save the matrix’s data pointer as a void * in the struct. When you need to access elements, declare a pointer to a VLA of the appropriate column size, point it at that void *, and then use normal matrix[row][col] indexing. Without VLAs you’d instead have to compute element addresses yourself by manually offsetting into a one-dimensional array.

    code:

    #include <stdio.h>
    #include <stdlib.h>
    
    // A structure to hold a single matrix's metadata and data pointer
    typedef struct {
        size_t rows;    // number of rows
        size_t cols;    // number of columns
        int *data;      // pointer to a flat array of size rows*cols
    } Matrix;
    
    // Function to safely allocate memory and exit on failure
    static void *safe_malloc(size_t bytes) {
        void *ptr = malloc(bytes);
        if (!ptr) {
            fprintf(stderr, "Error: memory allocation of %zu bytes failed.\n", bytes);
            exit(EXIT_FAILURE);
        }
        return ptr;
    }
    
    // Read a single integer from stdin with prompt and error checking
    static int read_int(const char *prompt) {
        int value;
        printf("%s", prompt);
        if (scanf("%d", &value) != 1) {
            fprintf(stderr, "Error: invalid integer input.\n");
            exit(EXIT_FAILURE);
        }
        return value;
    }
    
    // Read a matrix from stdin into a Matrix struct
    static void read_matrix(Matrix *M, int index) {
        // Read dimensions
        int r = read_int("");
        if (r <= 0) {
            fprintf(stderr, "Error: number of rows must be positive.\n");
            exit(EXIT_FAILURE);
        }
        int c = read_int("");
        if (c <= 0) {
            fprintf(stderr, "Error: number of columns must be positive.\n");
            exit(EXIT_FAILURE);
        }
        M->rows = (size_t)r;
        M->cols = (size_t)c;
    
        // Allocate space for all elements in one flat block
        M->data = safe_malloc(M->rows * M->cols * sizeof *M->data);
    
        // Read elements directly into the flat array
        for (size_t i = 0; i < M->rows; ++i) {
            for (size_t j = 0; j < M->cols; ++j) {
                printf("Enter element [%zu][%zu] of matrix %d: ", i+1, j+1, index + 1);
                if (scanf("%d", &M->data[i * M->cols + j]) != 1) {
                    fprintf(stderr, "Error: invalid matrix element input.\n");
                    exit(EXIT_FAILURE);
                }
            }
        }
    }
    
    // Print a single matrix to stdout
    static void print_matrix(const Matrix *M, int index) {
        printf("Matrix %d (%zux%zu):\n", index + 1, M->rows, M->cols);
        for (size_t i = 0; i < M->rows; ++i) {
            for (size_t j = 0; j < M->cols; ++j) {
                printf("%d ", M->data[i * M->cols + j]);
            }
            putchar('\n');
        }
    }
    
    int main(void) {
        // Ask for number of matrices
        int n = read_int("Enter the number of matrices: ");
        if (n < 0) {
            fprintf(stderr, "Error: number of matrices cannot be negative.\n");
            return EXIT_FAILURE;
        }
    
        // Allocate an array of Matrix structs
        Matrix *matrices = safe_malloc(n * sizeof *matrices);
    
        // Read each matrix
        for (int i = 0; i < n; ++i) {
            printf("Reading dimensions for matrix %d:\n", i+1);
            read_matrix(&matrices[i], i);
        }
    
        // Print all matrices
        for (int i = 0; i < n; ++i) {
            print_matrix(&matrices[i], i);
        }
    
        // Clean up
        for (int i = 0; i < n; ++i) {
            free(matrices[i].data);
        }
        free(matrices);
    
        return EXIT_SUCCESS;
    }