I am new to using Valgrind and have problems debugging the code, since it works except for what I assume are memory leaks on the marked line. Am I allocating the wrong size here?
Field *createField(unsigned int xsize, unsigned int ysize) {
/* Alright! Let's start off by assigning an new field that we can return.*/
unsigned int i, j;
Field *returnField;
returnField = malloc(sizeof(Field));
if(returnField == NULL) {
return NULL;
}
returnField->xsize = xsize;
returnField->ysize = ysize;
returnField->cells = malloc(ysize * sizeof(State *)); // memory leaks?!
if(returnField->cells == NULL) {
free(returnField);
return NULL;
}
/* Alright, now we have the y dimension pointer allocated. It's time
* to move on to the x dimension*/
for (j = 0; j < ysize; j++) {
returnField->cells[j] = malloc(xsize * sizeof(State));
if (returnField->cells[j] == NULL) {
for (i = 0; i < j; i++) {
free(returnField->cells[i]);
}
free(returnField);
return NULL;
}
for (i = 0; i < xsize; i++) {
returnField->cells[j][i] = DEAD;
}
}
return returnField;
}
/* Free memory allocated for field <f>.
*/
void releaseField(Field *f)
{
unsigned int j;
for (j = 0; j < f->ysize; j++) {
free(f->cells[j]);
}
free(f);
}
Below is the header containing the structures:
typedef enum {
DEAD,
ALIVE
} State;
typedef struct {
unsigned int xsize, ysize;
State **cells;
} Field;
You allocate memory to hold the cell pointers:
returnField->cells = malloc(ysize * sizeof(State *));
But you never free that memory. You do free the individual cells, but never the cell pointer itself:
if (returnField->cells[j] == NULL) {
for (i = 0; i < j; i++) {
free(returnField->cells[i]);
}
free(returnField->cells);
// ^^ This was missing
free(returnField);
return NULL;
}
The same problem appears in your releaseField()
implementation. I'd even suggest making it robust against partial allocation:
/* Free memory allocated for field <f>.
*/
void releaseField(Field *f)
{
unsigned int j;
if (f != NULL) {
if (f->cells != NULL) {
for (j = 0; j < f->ysize; j++) {
free(f->cells[j]);
}
}
// free cell pointer array memory, too
free(f->cells);
free(f);
}
}
Also replace returnField->cells = malloc(ysize * sizeof(State *));
by
returnField->cells = calloc(ysize, sizeof(State *));
Do the same thing when allocating the returnField
struct itself and you can even use releaseField()
for partially allocated fields and thus avoid code duplication:
returnField = calloc(1, sizeof(Field));
This way, you should be able to simply call releaseField()
even when you only have a partially allocacted field structure.
This might not be the real problem but you are not deallocating the memory allocated for cells
in this block.
if (returnField->cells[j] == NULL) {
for (i = 0; i < j; i++) {
free(returnField->cells[i]);
}
// Need to deallocate returnField->cells
// Add the following line.
free(returnField->cells);
free(returnField);
return NULL;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.