I've been working on a little project that deals with matrix computations in C.
I was doing some testing against the code I wrote and came across some incredibly confusing behaviour.
Before I get into the question, here is some of the relevant code.
Matrix Definition:
typedef struct
{
double **matrix;
int rows;
int cols;
int dimensions[2];
char *str_dims;
} Matrix;
When I initialize a matrix I allocate memory using malloc for the number of rows, then iterate over the rows allocating memory for all of the columns using calloc so they are 0 initialized.
void init_matrix(Matrix *x, int i, int j)
{
x->matrix = malloc(x->rows * sizeof(double *));
for (int i = 0; i < x->rows; i++)
x->matrix[i] = calloc(x->cols, sizeof(double));
}
I also have the functionality of generating a random matrix,
Matrix get_rand_matrix(int i, int j)
{
Matrix x;
init_matrix(&x, i, j);
srand(time(NULL));
for(int i = 0; i < x.rows; i++)
for(int j = 0; j < x.cols; j++)
x.matrix[i][j] = rand();
return x;
}
Confusing Behaviour
Asides from the code most likely being pretty horrendous by the standards of the ancients, I had thought that it was working properly. However, by luck of the draw, when I was doing some testing (printing the matrix) I mindlessly incremented the loop responsible for iterating over the columns of the matrix by 1 and this was the output that I received. (Formatted for your viewing pleasure.)
+-------------+--------------+-----+
|739979002.00 | 1854570721.00| 0.00|
|130427701.00 | 402893063.00 | 0.00|
|1973118592.00| 135400441.00 | 0.00|
|1707001127.00| 1093842609.00| 0.00|
+----------------------------------+
Where the expected output would have been,
+-------------+--------------+
|739979002.00 | 1854570721.00|
|130427701.00 | 402893063.00 |
|1973118592.00| 135400441.00 |
|1707001127.00| 1093842609.00|
+----------------------------+
The code that generated this just to keep you out of the dark,
Matrix m = get_rand_matrix(4, 2);
for(int i = 0; i < m.rows; i++)
{
for(int j = 0; j < m.cols + 1; j++)
printf("%.2lf ", m.matrix[i][j]);
printf("\n");
}
Question
Now, I have honestly no idea why I am not getting a segfault and have access to zero-initialized elements outside of (what I would have thought to be) the bounds of the memory that was allocated. I can only assume its an error on my part by conflating malloc
and calloc
together, but then again, I also don't see why this wouldn't work.
Does anyone know what is going on, why are there 0 initialized doubles outside of the bounds of the allocated memory? I am rather new to C and memory allocation in general and this has completely dazzled me.
Interesting addition
Some of the elements seem to repeat when you increase the column loop exiting condition (Generated with j < m.cols + 5
)
+-------------------------------------------------------------------------------+
|549092153.00 | 1317836633.00 | 0.00| 0.00 | 218607745.00 |1326282480.00 | 0.00 |
|218607745.00 | 1326282480.00 | 0.00| 0.00 | 715372192.00 |976468777.00 | 0.00 |
|715372192.00 | 976468777.00 | 0.00| 0.00 | 103851159.00 |363785358.00 | 0.00 |
|103851159.00 | 363785358.00 | 0.00| 0.00 | 0.00 | 0.00 | 0.00 |
+-------------------------------------------------------------------------------+
I increased the increment to +1000 and it still continues to print 0.00 and repeated numbers.