Reputation: 2127
I've been trying to write a little matrix framework in C. The problem is that acessing the matrix's components is modifying them somehow. You can see that the matrix a
gets its elements changed in a weird way after being passed to matrix_scalar_multiply
.
You can run the code at jdoodle.com/a/13t7
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
typedef struct Matrix
{
int lines; //number of lines
int columns; //number of columns
float *numbers; //elements of our matrix
} Matrix;
void
matrix_create (Matrix * a, const float *array, int lines, int columns)
{
a->numbers = (float *) malloc (lines * columns);
a->lines = lines;
a->columns = columns;
for (int i = 0; i < a->lines; i++)
for (int j = 0; j < a->columns; j++)
*(a->numbers + j + i * columns) = *(array + j + i * columns);
}
void
matrix_init (Matrix * a, int lines, int columns)
{
a->numbers = (float *) malloc (lines * columns);
a->lines = lines;
a->columns = columns;
}
float *
matrix_element (Matrix * a, int line, int column)
{
return a->numbers + column + line * a->columns;
}
int
matrix_scalar_multiply (float scalar, Matrix * a, Matrix * answer)
{
matrix_init (answer, a->lines, a->columns);
for (int i = 0; i < answer->lines; i++)
for (int j = 0; j < answer->columns; j++)
*matrix_element (answer, i, j) = *matrix_element (a, i, j) * scalar;
return 0;
}
void
matrix_print (Matrix * a)
{
for (int i = 0; i < a->lines; i++)
{
for (int j = 0; j < a->columns; j++)
printf ("%f ", *matrix_element (a, i, j));
printf ("\n");
}
printf ("\n");
}
#include <stdio.h>
int
main ()
{
Matrix a;
Matrix b;
float aa[4][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12} };
matrix_create (&a, aa, 4, 3);
matrix_print (&a);
matrix_scalar_multiply (3.0, &a, &b);
matrix_print (&a);
matrix_print (&b);
return 0;
}
The output:
1.000000 2.000000 3.000000
4.000000 5.000000 6.000000
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
1.000000 2.000000 3.000000
4.000000 5.000000 6.000000
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
3.000000 6.000000 9.000000
12.000000 15.000000 18.000000
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
I've tried many things but couldn't find why some elements of matrix a
are getting changed. If I comment matrix_init (answer, a->lines, a->columns);
everything goes fine. However, you can see that I don't even pass a
as argument in matrix_init
.
Upvotes: 1
Views: 49
Reputation: 164699
The problem is here.
a->numbers = (float *) malloc (lines * columns);
malloc
allocates bytes, so this allocates lines * columns
bytes. But a->numbers
is an array of floats
which are typically 4 bytes each. You've allocated only 25% of the necessary memory. When allocating memory for an array, you must also include the size of the elements.
a->numbers = malloc (lines * columns * sizeof(float));
(Side note: it's unnecessary to cast the result of malloc
)
You can buy yourself a little more protection by using the size of *a->numbers
instead. Then if the type of a->numbers
changes, like to a double *
, the allocation will still be correct.
a->numbers = malloc (lines * columns * sizeof(*a->numbers));
Upvotes: 1