Search code examples
cstructcoding-styleabstract-data-type

Should I prefer call destroy, or free mebmers manually, if allocation failed


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?


Solution

  • 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.