I've debugged my program and every time it reaches to free the memory blocks that I allocated, it crashes. I've made sure that I deallocated my memory the exact same way I allocated it but it still crashes(sometimes I'm lucky and it does not crash). I've made sure that I have correctly move each pointer to their correct during allocation but it still crashes.
Here is my code.
MatrixTest.c
Code:
#include <stdio.h>
#include <stdlib.h>
#include "Matrix.h"
int main()
{
matrix mat;
int element;
int i, j, errCheck; /*Change element to the appropriate data type you will be workng with.*/
const int ROWS = 5;
const int COL = 5;
/*You can change sizeof() for any data type you want(integers, char arrays etc)*/
errCheck = createMatrix(&mat, ROWS, COL, sizeof(int));
/*If we were not able to successfully allocate memory*/
if(errCheck == -1)
{
printf("Couldn't not allocate any more memory.");
exit(EXIT_FAILURE);
}
for(i = 0; i < ROWS; i++)
{
for(j = 0; j < COL; j++)
{
/*
Note, when ever you decide to use scanf, make sure that first character you enter is a space else
a newline will be consumed in the process.
*/
errCheck = scanf(" %d", &element);
/*Make sure that scanf did not fail. Scanf returns an integer based on the number of successful entries. */
if(errCheck == 1)
{
setElement(&mat, i, j, &element);
}
}
}
printf("\n");
for(i = 0; i < ROWS; i++)
{
for(j = 0; j < COL; j++)
{
/*Returns void * so I must cast it to the appropriate type.*/
element = *(int*)getElement(&mat, i, j);
printf("%d ", element);
}
printf("\n");
}
freeMatrix(&mat);
return 0;
}
Matrix.h
Code:
#ifndef MATRIX_H_INCLUDED
#define MATRIX_H_INCLUDED
typedef struct Matrix
{
void **data;
size_t rows;
size_t columns;
size_t memSize;
}matrix;
int createMatrix(matrix *, const size_t, const size_t, const size_t);
void *getElement(matrix *, const size_t, const size_t);
void setElement(matrix *, const size_t, const size_t, const void *);
void freeMatrix(matrix *);
#endif /* MATRIX_H_INCLUDED */
Matrix.c
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Matrix.h"
int createMatrix(matrix *mat, const size_t rows, const size_t columns, const size_t memSize)
{
void **data = malloc(sizeof(void *) * rows);
data[0] = malloc(memSize * rows * columns);
if(data != NULL || data[0] != NULL)
{
size_t i;
for (i = 1; i < rows; i++)
{
data[i] = (char *)data[0] + (i * columns * memSize);
}
mat->rows = rows;
mat->columns = columns;
mat->memSize = memSize;
mat->data = data;
return 1;
}
return -1;
}
void setElement(matrix *mat, const size_t x, const size_t y, const void *data)
{
/*
Remember this formula. (i * numOfColumns) + j to traverse a 2D array in a 1D fashion(This formula only applies to Row Major Order Arrays).
*/
size_t offset = ((x * mat->columns) + y) * mat->memSize;
memcpy(mat->data + offset, data, mat->memSize);
}
void *getElement(matrix *mat, const size_t x, const size_t y)
{
size_t offset = ((x * mat->columns) + y) * mat->memSize;
return mat->data + offset;
}
void freeMatrix(matrix *mat)
{
if(mat->data != NULL)
{
/*Set back every back to their default values to preserve invariants.*/
free(mat->data[0]);
free(mat->data);
mat->data = NULL;
mat->rows = 0;
mat->columns = 0;
mat->memSize = 0;
}
}