Memory leak in C, 2d array in struct -
i need memory leaks. ive been staring @ code while , still cant find out leaks. think freeing everything, unnecessarily, there still something.
code
#include <stdio.h> #include <stdlib.h> struct matrix{ int **data; int rows; int columns; }; struct matrix matrix_op(struct matrix, struct matrix, char); int** _2d_array(int,int); void print_matrix(struct matrix); void _2d_array_free(int**, int); void _scalar_mul(struct matrix*, int); int** _2d_array(int x,int y){ int** arr; arr = malloc(sizeof(int*)*x); for(int = 0; i<x;++i){ arr[i] = malloc(sizeof(int)*y); } return arr; } void _scalar_mul(struct matrix* a, int s){ (int x = 0; x < a->rows; ++x) { (int y = 0; y < a->columns; ++y) a->data[x][y] *= s; } } void _2d_array_free(int** array, int x){ (int = 0; < x; ++i) { free(array[i]); } free(array); } void exit_err(int err, char* message){ fprintf(stderr,message); exit(err); } struct matrix read_matrix(int x, int y){ struct matrix matrix; matrix.rows = x; matrix.columns = y; matrix.data = _2d_array(x,y); (int = 0; < x; ++i) { (int j = 0; j < y; ++j) { if(scanf("%d", &matrix.data[i][j])==0) exit_err(100,"error...\n"); } } return matrix; } struct matrix matrix_op(struct matrix a, struct matrix b, char op) { struct matrix res_matrix; int** result; if (op == '*') { if(a.columns==b.rows) { result = _2d_array(a.rows, b.columns); (int x = 0; x < a.rows; ++x) { (int y = 0; y < b.columns; ++y) { int sum = 0; (int z = 0; z < a.columns; z++) { sum += a.data[x][z] * b.data[z][y]; } result[x][y] = sum; } } } else exit_err(100,"error...\n"); res_matrix.data = result; res_matrix.rows = a.rows; res_matrix.columns = b.columns; } else { if (op == '-') { _scalar_mul(&b,-1); } result = _2d_array(a.rows,a.columns); (int x = 0; x < a.rows; ++x) { (int y = 0; y < a.columns; ++y){ result[x][y]=a.data[x][y]+b.data[x][y]; } } res_matrix.data = result; res_matrix.rows = a.rows; res_matrix.columns = a.columns; } return res_matrix; } void print_matrix(struct matrix matrix){ printf("%d %d\n",matrix.rows, matrix.columns); for(int x = 0; x<matrix.rows;++x){ for(int y = 0; y<matrix.columns;++y){ if(y==0)printf("%d", matrix.data[x][y]); else printf(" %d",matrix.data[x][y]); } printf("\n"); } } int main(){ int x,y,count; count=0; char op='\0'; struct matrix* matrices = malloc(0); while(1){ scanf("%d %d", &x, &y); matrices = realloc(matrices,sizeof(struct matrix)*(++count)); matrices[count-1]=read_matrix(x,y); if(op=='-') { _scalar_mul(&matrices[count - 1], -1); }; if(op=='*') { struct matrix result = matrix_op(matrices[count-2], matrices[count-1], op); _2d_array_free(matrices[count-1].data, matrices[count-1].rows); matrices[count-1] = result; _2d_array_free(matrices[count-2].data, matrices[count-2].rows); matrices[count-2].rows=0; } if(scanf("\n%c", &op)==eof) break; } struct matrix res; res.data = _2d_array(3,3); res.rows = 3; res.columns = 3; res = matrices[0]; (int = 1; < count; ++i) { if(res.rows>0&&matrices[i].rows>0) { struct matrix tmp = matrix_op(res, matrices[i], '+'); _2d_array_free(res.data, res.rows); res.rows = 0; res = tmp; } else if (res.rows==0){ _2d_array_free(res.data, res.rows); res.rows = 0; res = matrices[i]; } } print_matrix(res); _2d_array_free(res.data, res.rows); (int j = 0; j < count; ++j) { if(matrices[j].rows!=0){ _2d_array_free(matrices[j].data,matrices[j].rows); } } free(matrices); }
valgrind out:
==25== invalid read of size 8 ==25== @ 0x4008b5: _2d_array_free (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== 0x401038: main (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== address 0x51fc0d0 0 bytes inside block of size 24 free'd ==25== @ 0x4c2bd57: free (vg_replace_malloc.c:530) ==25== 0x4008d7: _2d_array_free (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== 0x400f51: main (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== block alloc'd @ ==25== @ 0x4c2ac3d: malloc (vg_replace_malloc.c:299) ==25== 0x4007ac: _2d_array (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== 0x400936: read_matrix (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== 0x400d46: main (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== ==25== invalid free() / delete / delete[] / realloc() ==25== @ 0x4c2bd57: free (vg_replace_malloc.c:530) ==25== 0x4008bf: _2d_array_free (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== 0x401038: main (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== address 0x51fc130 0 bytes inside block of size 28 free'd ==25== @ 0x4c2bd57: free (vg_replace_malloc.c:530) ==25== 0x4008bf: _2d_array_free (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== 0x400f51: main (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== block alloc'd @ ==25== @ 0x4c2ac3d: malloc (vg_replace_malloc.c:299) ==25== 0x4007df: _2d_array (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== 0x400936: read_matrix (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== 0x400d46: main (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== ==25== invalid free() / delete / delete[] / realloc() ==25== @ 0x4c2bd57: free (vg_replace_malloc.c:530) ==25== 0x4008d7: _2d_array_free (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== 0x401038: main (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== address 0x51fc0d0 0 bytes inside block of size 24 free'd ==25== @ 0x4c2bd57: free (vg_replace_malloc.c:530) ==25== 0x4008d7: _2d_array_free (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== 0x400f51: main (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== block alloc'd @ ==25== @ 0x4c2ac3d: malloc (vg_replace_malloc.c:299) ==25== 0x4007ac: _2d_array (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== 0x400936: read_matrix (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== 0x400d46: main (in /mnt/c/users/wm/clionprojects/hw4/main) ==25== ==25== ==25== heap summary: ==25== in use @ exit: 60 bytes in 4 blocks ==25== total heap usage: 19 allocs, 19 frees, 432 bytes allocated ==25== ==25== leak summary: ==25== lost: 24 bytes in 1 blocks ==25== indirectly lost: 36 bytes in 3 blocks ==25== possibly lost: 0 bytes in 0 blocks ==25== still reachable: 0 bytes in 0 blocks ==25== suppressed: 0 bytes in 0 blocks ==25== rerun --leak-check=full see details of leaked memory ==25== ==25== counts of detected , suppressed errors, rerun with: -v ==25== error summary: 7 errors 3 contexts (suppressed: 0 0)
input
3 7 -42 8 -62 0 7 46 3 7 11 45 89 -39 -27 70 -35 -5 0 -99 -50 -14 46 + 3 7 73 -88 -45 94 -41 -67 -66 0 22 30 29 72 -91 76 -95 -83 -46 -88 28 69 -62
output
3 7 31 -80 -107 94 -34 -21 -63 7 33 75 118 33 -118 146 -130 -88 -46 -187 -22 55 -16
output ok, memory leak , valgrind errors undesirable.
thanks help!
one problem this:
struct matrix res; res.data = _2d_array(3,3); res.rows = 3; res.columns = 3; res = matrices[0];
you define res
, initialize it, reassign matrices[0]
overwrite data initialized, including pointer data allocated.
also:
_2d_array_free(res.data, res.rows); (int j = 0; j < count; ++j) { if(matrices[j].rows!=0){ _2d_array_free(matrices[j].data,matrices[j].rows); } }
here res.data
points data allocated 1 of entries in matrices
, attempting free data twice wrong. simple solution not call _2d_array_free
res.data
.
lastly little note style , naming: should avoid using symbol-names leading underscores. if you're not careful might use reserved symbol (underscore followed upper-case letter or underscore). leading underscores used internally compiler , standard library.
Comments
Post a Comment