Assuming I have an ADT, and some functions:
typedef struct myADT_t *myADT;
struct myADT_t {
T1 *m1;
T2 *m2;
};
myADT myADT_create() {
myADT new_myADT=malloc(sizeof(*new_myADT));
if (!new_myADT) return NULL;
if (!(new_myADT->m1=malloc(sizeof(T1)))) {
free(new_myADT);
return NULL;
}
if (!(new_myADT->m2=malloc(sizeof(T2)))) {
free(new_myADT->m1);
free(new_myADT);
return NULL;
}
//put some values in *m1 and *m2
return new_myADT;
}
void myADT_destroy(myADT var) {
if (!var) return;
free(var->m2);
free(var->m1);
free(var);
}
I was told, that if the last allocation failed, I can call myADT_destroy
, instead of free new_myADT->m1
and new_myADT
manually. However, it seems to me that although it will work, I shouldn't call myADT_destroy
with a not-successfully-created object. Also, if I will add members to myADT_t
, it may make things difficult.
What should I prefer?
If you take care to initialize the structure you allocate to zero (either explicitly or by using calloc
) then you can call your myADT_destroy
function on failure. The C specification explicitly allows free
to be called with a NULL
pointer.
Doing it that way, you can simplify the myADT_create
function substantially, and also creates some symmetry.