Is this a good way to free memory?

后端 未结 5 712
忘掉有多难
忘掉有多难 2020-12-14 13:58

The function for freeing an instance of struct Foo is given below:

void DestroyFoo(Foo* foo)
{
    if (foo) free(foo);
}

A

5条回答
  •  再見小時候
    2020-12-14 14:32

    void destroyFoo(Foo** foo)
    {
        if (!(*foo)) return;
        Foo *tmpFoo = *foo;
        *foo = NULL;
        memset(tmpFoo, 0, sizeof(Foo));
        free(tmpFoo);
    }
    

    Your colleague code is bad because

    • it will crash if foo is NULL
    • there's no point in creating additional variable
    • there's no point in setting the values to zeros
    • freeing a struct directly doesn't work if it contain things that has to be freed

    I think what your colleague might have in mind is this use-case

    Foo* a = NULL;
    Foo* b = createFoo();
    
    destroyFoo(NULL);
    destroyFoo(&a);
    destroyFoo(&b);
    

    In that case, it should be like this. try here

    void destroyFoo(Foo** foo)
    {
        if (!foo || !(*foo)) return;
        free(*foo);
        *foo = NULL;
    }
    

    First we need to take a look at Foo, let's assume that it looks like this

    struct Foo
    {
        // variables
        int number;
        char character;
    
        // array of float
        int arrSize;
        float* arr;
    
        // pointer to another instance
        Foo* myTwin;
    };
    

    Now to define how it should be destroyed, let's first define how it should be created

    Foo* createFoo (int arrSize, Foo* twin)
    {
        Foo* t = (Foo*) malloc(sizeof(Foo));
    
        // initialize with default values
        t->number = 1;
        t->character = '1';
    
        // initialize the array
        t->arrSize = (arrSize>0?arrSize:10);
        t->arr = (float*) malloc(sizeof(float) * t->arrSize);
    
        // a Foo is a twin with only one other Foo
        t->myTwin = twin;
        if(twin) twin->myTwin = t;
    
        return t;
    }
    

    Now we can write a destroy function oppose to the create function

    Foo* destroyFoo (Foo* foo)
    {
        if (foo)
        {
            // we allocated the array, so we have to free it
            free(t->arr);
    
            // to avoid broken pointer, we need to nullify the twin pointer
            if(t->myTwin) t->myTwin->myTwin = NULL;
        }
    
        free(foo);
    
        return NULL;
    }
    

    Test try here

    int main ()
    {
        Foo* a = createFoo (2, NULL);
        Foo* b = createFoo (4, a);
    
        a = destroyFoo(a);
        b = destroyFoo(b);
    
        printf("success");
        return 0;
    }
    

提交回复
热议问题