How can I free memory allocated in this struct
struct image_t {
char type[3];
int **ptr;
int width;
int height;
};
In the first function I made these allocations:
struct image_t *struktura = (struct image_t *)malloc(sizeof(struct image_t));
int **ptr = (int**)malloc(struktura->height * sizeof(int*));
for (i = 0; i < struktura->height; i++) {
*(ptr + i) = (int *)malloc(struktura->width * sizeof(int));
if (*(ptr + i) == NULL) {
break;
}
}
In the second function I must free allocated memory so I tried to free memory something like this but it does not work
void destroy_image(struct image_t **m) {
if (m != NULL) {
if (*m != NULL) {
if ((*m)->ptr != NULL) {
for (int i = 0; i < (*m)->height; i++) {
free(*((*m)->ptr + i));
}
free((*m)->ptr);
free(*m);
}
}
}
}
I can't change declaration of the destroy function so there must be double pointer on struct.
In order for your destroy function to work properly, all pointers in the pointer array must be either valid or null. Memory returned by malloc()
is uninitialized so breaking out of the loop in the allocation function leaves the rest of the pointer array uninitialized, hence should not be passed to free()
.
Also note the you should test for allocation failure of the structure pointer and the pointer array. Furthermore the width
and height
members of the newly allocated structure are unintialized: you should use function arguments to initialize them.
The destroy_image
function should probably set *m
to NULL
after deallocation and must free(*m);
even if (*m)->ptr
is a null pointer.
Here are solutions for this issue:
calloc()
(a good idea in all cases) orheight
to the number of successfully allocated pointers.NULL
NULL
.Here is a modified version:
#include <stdlib.h>
struct image_t {
char type[3];
int **ptr;
int width;
int height;
};
struct image_t *allocate_image(int width, int height) {
struct image_t *struktura = calloc(1, sizeof(*struktura));
if (struktura == NULL)
return NULL;
// should initialize struktura->type too
struktura->width = width;
struktura->height = height
struktura->ptr = calloc(height, sizeof(*struktura->ptr));
if (struktura->ptr == NULL) {
free(struktura);
return NULL;
}
for (int i = 0; i < height; i++) {
struktura->ptr[i] = calloc(sizeof(*struktura->ptr[i]), width);
if (struktura->ptr[i] == NULL) {
// Iterate downwards on index values of allocated rows
// (i --> 0) is parsed as (i-- > 0)
// this test works on signed and unsigned index types, unlike (--i >= 0)
while (i --> 0) {
free(struktura->ptr[i]);
}
free(struktura->ptr);
free(struktura);
return NULL;
}
}
return struktura;
}
void destroy_image(struct image_t **m) {
if (m != NULL) {
struct image_t *p = *m;
if (p != NULL) {
if (p->ptr != NULL) {
for (int i = 0; i < p->height; i++) {
free(p->ptr[i]);
}
free(p->ptr);
}
free(p);
*m = NULL;
}
}
}