Reputation: 139
Working on some C code working with Matrices. I have created a Matrix struct to make it easier to create many instances of it quickly and efficiently but I am not sure why my code is leaking memory. Currently I have the following code:
typedef struct
{
size_t rows;
size_t cols;
double ** value;
}
*Matrix;
Matrix matCreate( size_t rows, size_t cols )
{
if(rows<=0 || cols<=0)
{
return NULL;
}
Matrix mat = (Matrix) malloc(sizeof(Matrix));
mat->rows = rows;
mat->cols = cols;
mat->value = (double **) malloc(rows*sizeof(double*));
for (int i=0; i< rows;i++)
{
mat->value[i] = (double *) malloc(cols * sizeof(double));
for( int j=0; j< cols;j++)
{
mat->value[i][j] = 0;
if(rows == cols && i==j )
{
mat->value[i][j] = 1;
}
}
}
return mat;
}
And I am getting the following memory leaks after running valgrind. When running the code it compiles completely without error and still outputs the right output.
==23609== Invalid write of size 8
==23609== at 0x400800: matCreate
==23609== by 0x4010E2: main
==23609== Address 0x5203048 is 0 bytes after a block of size 8 alloc'd
==23609== at 0x4C2DB8F: malloc
==23609== by 0x4007E8: matCreate
==23609== by 0x4010E2: main
==23609==
==23609== Invalid write of size 8
==23609== at 0x40081B: matCreate
==23609== by 0x4010E2: main
==23609== Address 0x5203050 is 8 bytes after a block of size 8 alloc'd
==23609== at 0x4C2DB8F:
==23609== by 0x4007E8: matCreate
==23609== by 0x4010E2: main
==23609==
==23609== Invalid read of size 8
==23609== at 0x40082F: matCreate
==23609== by 0x4010E2: main
==23609== Address 0x5203050 is 8 bytes after a block of size 8 alloc'd
==23609== at 0x4C2DB8F: malloc
==23609== by 0x4007E8: matCreate
==23609== by 0x4010E2: main
Upvotes: 3
Views: 1461
Reputation: 206727
The line
Matrix mat = (Matrix) malloc(sizeof(Matrix));
is not good. It does not allocate enough memory. As a consequence, your program has undefined behavior.
size(Memory)
evaluates to the size of a pointer, not the size of the struct
.
It needs to be:
Matrix mat = malloc(sizeof(*mat));
Defining Matrix
that is really a pointer is not good coding practice. It will lead to confusion. I suggest defining it as:
typedef struct
{
size_t rows;
size_t cols;
double ** value;
} Matrix;
and then use:
Matrix* matCreate( size_t rows, size_t cols ) { ... }
...
Matrix* mat = malloc(sizeof(*mat));
See Do I cast the result of malloc?
Upvotes: 3