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
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;
}