#include <stdio.h>
int main()
{
int matrix;
printf("ENTER NUMBER OF MATRICES\n");
scanf("%d", &matrix);
getchar();
int row[matrix], column[matrix];
for (int m = 0; m < matrix; m++) {
printf("ENTER NUMBER OF ROWS IN %d MATRICE\n", m + 1);
scanf("%d", &row[m]);
getchar();
printf("ENTER NUMBER OF column IN %d MATICE\n", m + 1);
scanf("%d", &column[m]);
getchar();
int x[m][row[m]][column[m]];
int g = 1;
printf("ENTER ALL ELEMENT LEFT TO RIGHT\n");
for (int j = 0; j < row[m]; j++) {
for (int u = 0; u < column[m]; u++) {
printf("%d\n", g);
scanf("%d", &x[m][j][u]);
g = g + 1;
}
}
for (int k = 0; k < row[m]; k++) {
printf("|");
for (int l = 0; l < column[m]; l++) {
printf("%d", x[m][k][l]);
if (l < column[m] - 1) {
printf(" ");
}
}
printf("|");
printf("\n");
}
}
return 0;
}
OUTPUT:
ENTER NUMBER OF MATRICES
1
ENTER NUMBER OF ROWS IN 1 MATRICE
1
ENTER NUMBER OF column IN 1 MATICE
2
ENTER ALL ELEMENT LEFT TO RIGHT
1 // COUNTING JUST FOR USER
3 // INPUT 1
2 // COUNTING
4 // INPUT 2
3 //WHY IS IT ASKING ME THIRD ELEMENT WHEN I HAVE SET SIZE OF
MATRIX TO BE 1-2
2 // INPUT 3
|3 4 2|
EXPECTATIONS:
ENTER NUMBER OF MATRICES
1
ENTER NUMBER OF ROWS IN 1 MATRICE
1
ENTER NUMBER OF column IN 1 MATICE
2
ENTER ALL ELEMENT LEFT TO RIGHT
1
3
2
4
|3 4|
HERE AS YOU CAN SEE I GIVE ROWS AND COLUMN TO BE 1-2 BUT STILL MATRIX SIZE IS 1 ROW AND 3 COLUMN FOR SOME REASON THE THE FIRST INPUT GIVE TO MY MATRIX IS BEING SET AS NO. OF TIMES FOR LOOP SHOULD RUN FOR AND NO. OF COLUMN IN MATRIX
i have made a program with matrix however 'for' loop is running different from my expectations i could not understand what value is 'for' loop taking as input to run for , i have managed to figure that for some reason the first value in 'for' loop's scanf is what is setting no. of columns for matrix and determining the turns the loop is going to run for. since i could not figure solution to my problem i request you to help me resolve this error.
The problem in your loop lies here:
int x[m][row[m]][column[m]];
// ...
scanf("%d", &x[m][<whatever>][<whatever>]);
This code first produces a three-dimensional array containing m
matrices each with row[m]
rows and column[m]
columns and later on accesses this array out of bounds by x[m]
– valid indices are in the range of [0; m-1]
, note especially: m
not included! You don't actually don't even produce any matrices at all for m == 0
(zero sized arrays can be used in a struct to produce flexible array members...).
Accessing arrays out of bounds is undefined behaviour, so just anything might happen including your programme running as expected (on some lucky input), your programme crashing or (worst) showing unexpected behaviour as you experienced.
What happens under the hoods is that – as obviously operating on an architecture with top-down stack – the array row
is placed at some high memory address, column
placed in front of row
(some lower memory address) and finally x
on front of column
. Then when accessing x
out of bounds you access some memory address higher to the one of x
, and guess, there are the arrays row
and column. Thus by writing to x
out of bounds you accidentally change the values in row
and column
or at least one of and thus change the loop limits, resulting in the behaviour you see (you might experiment with other matrix values and observe how the behaviour changes...).
Side note: The concrete value of m
is irrelevant, assuming x
is placed immediately in front of columns
then the address of x
is the address of b
with m*sizeof(*x)
subtracted, and x[m]
then again adds m*sizeof(*x)
to this address, thus x[m][0][0]
always accesses column[0]
...
How to solve: As long as you do the entire matrix processing within the loop then you can create the matrix as a simple two-dimensional array:
for(int m = 0; m < c; ++m)
{
// in this case actually sufficient here as well,
// as ordinary integers:
int row; int column;
// scan row and column
int matrix[row][column];
// now scan into matrix[r][c] with r and c iterating accordingly
}
If you want to maintain an array of matrices then you need to define this array before entering the loop! The problem that then arises: All array entries are required to be of equal size! With a single 3D array you'd need to first determine the sizes of all matrices and remember the the maximal dimenstions to use for all the matrices.
The alternative is allocating the matrices dynamically, however you need a way to properly handle them then.
I recommend using a dedicated struct for and mapping the 2D array of the matrix to a single one-dimenstional array, doing index calculations by hand, such as:
#include<stddef.h> // for size_t
struct Matrix
{
size_t rows, columns;
int* values;
// or alternatively with flexible array member:
int values[0];
};
int get(struct Matrix* matrix, size_t row, size_t column)
{
return matrix->values[row * matrix->columns + column];
}
void set(struct Matrix* matrix, size_t row, size_t column, int value)
{
matrix->values[row * matrix->columns + column] = value;
}
Finally you can allocate dynamically; either as
struct Matrix matrices[m] = { {0, 0, NULL} };
or with flexible array members as
struct Matrix* matrices[m] = { NULL };
Note that you need dynamic memory allocation anyway, either for the array referenced by the matrix by pointer or for the entire matrix struct in case of the flexible array member (I personally consider the latter approach a bit cleaner...):
Then allocation of the matrices within the loop occurs as follows:
size_t count;
scanf("%zu", &count);
for(size_t m = 0; m < count; ++m)
{
size_t rows, columns;
scanf("%zu", &rows);
scanf("%zu", &columns);
///////////////////////////////////////////////////
// pointer variant:
matrices[m].values = malloc(rows * columns * sizeof(*matrices[m].values));
if(!matrices[m].values)
{
// allocation failed!
// TODO: appropriate error handling!
// return or exit(-1) or ???
}
matrices[m].rows = rows;
matrices[m].columns = columns;
///////////////////////////////////////////////////
// flexible array member variant:
matrices[m] = malloc
(
// base size
sizeof(*matrices[m])
// plus size of array
+ rows * columns * sizeof(*matrices[m]->values)
);
if(!matrices[m])
{ /* again: error handling! */ }
matrices[m]->rows = rows;
matrices[m]->columns = columns;
///////////////////////////////////////////////////
// now scan the matrix entries
int* values = matrices[m].values; // pointer variant
int* values = matrices[m]->values; // flexible array member; note that the
// array decays to pointer automatically
// looping over rows and columns
scanf("%d", values++);
}
Finally: There's dynamically allocated memory, do not forget to free
it again:
for(size_t m = 0; m < count; ++m)
{
free(matrices[m].values); // array as pointer
free(matrices[m]); // flexible array member
}
Final note: All code entirely untested, if you find a bug please fix yourself...