Frage

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?

War es hilfreich?

Lösung

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.

Andere Tipps

By using myADT_destroy instead of all the free() when myADT_create fails, you just need to maintain one function if you need to add members to the structure. The C standard explicitly says that calling free(NULL) has no effect.

Of course, this implies that you will never add any other functionality that may have side-effects in the destroy function. This is mostly a matter of taste though, both solution will work and both have some minor potential inconvenience.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top