I have to create a matrix with pointers in dynamic memory in C, fill it with random numbers then print it.
This is part of a larger assignment from college (I had to do a whole library of functions for matrixes) but for the purposes of the post, I think I managed to track down and isolate the problematic bits. Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
int main()
{
int rows = 2;
int cols = 3;
int **matrix = malloc(sizeof(int*) * rows); //declaring and allocating dynamic memory for the matrix
for(int i=0;i<rows;i++)
*(matrix+i) = malloc(sizeof(int) * cols);
//generating random numbers for the matrix:
srand(time(NULL));
for(int i=0;i<rows;i++)
for(int j=0;j<cols;j++)
*(*(matrix+j)+i) = rand() % 20;
//printing matrix:
printf("{\t");
for(int i=0;i<rows;i++)
{
int j;
if(i>0)
printf("\t");
printf("{\t");
for(j=0;j<cols;j++)
printf("%d\t",*(*(matrix + j) + i));
printf("}");
if(i<rows-1)
printf("\n");
}
printf("\t}\n\n");
//destroying the matrix
for(int i=0;i<rows;i++)
free(matrix[i]);
free(matrix);
matrix = NULL;
return 0;
}
The debugger stops here:
*(*(matrix+j)+i) = rand() % 20;
Apparently, when trying to generate a random number for the first column of the second row (i.e. when it first changes rows) the debugger "cannot access memory" for that position, then the program crashes.
I tried changing the amount of rows and columns and I found it only crashes when row size is less than column size, which is weird because when it's equal or more, it works just fine.
I'm trying with 2 rows by 3 columns. Expectation:
{ { 5 17 3 }
{ 1 8 11 } }
What actually happens:
Process returned -1073741819 (0xC0000005)
Values of the variables when the debugger stops (at generating random numbers):
i = 0
j = 2
**(matrix + 2) (aka matrix[0][2]) = Cannot access memory at address 0xabababababababab
At first I suspected I messed up when allocating memory for the matrix, but as I said when the matrix is square it does work fine, so I really don't know what's the issue here. I know the stackOverflow community doesn't like when someone posts "I don't know what I did wrong please help" kind of thing but I've really been a long time trying and couldn't get to the root of the problem.
Can someone please shed some light on this for me?
These nested for loops contain a bug
for(int i=0;i<rows;i++)
for(int j=0;j<cols;j++)
*(*(matrix+j)+i) = rand() % 20;
The pointer matrix
points to an array of pointers that in turn point to "rows". So the expression matrix + i
points to the i-th
"row". However instead you are using the index j
.
That is you need to write
*(*(matrix+i)+j) = rand() % 20;
instead of
*(*(matrix+j)+i) = rand() % 20;
Otherwise when the value of cols
is greater than the value of rows
the expression matrix + j
can access memory outside the allocated array of pointers (rows).
The same problem exists in this call of printf
printf("%d\t",*(*(matrix + j) + i));
where you have to write
printf("%d\t",*(*(matrix + i) + j));
That is you need actually to access an element matrix[i][j]
. This expression may be rewritten like
( *( matrix + i ) )[j]
that in turn may be rewritten like
*( *( matrix + i ) + j )
Or in other way it may be rewritten like
*( matrix[i] + j )
and then
*( *( matrix + i ) + j )
To raise your interest to the subscript operator investigate these equivalent expressions to access elements of a two-dimensional array declared for example like
T a[M][N];
The expressions are
a[i][j]
i[a][j]
j[a[i]]
j[i[a]]
*( *( a + i ) + j )
*( a[i] + j )
*( i[a] + j )
( *( a + i ) )[j]
j[*( a + i ) ]