Search code examples
cmallocfree

Cleanup function in C


I have a C program which allocates a few buffers which need to be cleared before the program exits execution. My main program looks like this

int main(int argc, char** argv){
    // Some code
    // ...
    // ...
    void* data1 = malloc(someSize);
    void* data2 = malloc(someSize);
    double* result = malloc(resultSize);
    double* buffer = malloc(buffSize);
    // Some code
    // ...
    // First exit point
    if(someExitcondition){
        // free all allocated memory
        exit(1);
    }
    // Some code
    // ...
    // Second exit point
    if(someOtherExitcondition){
        // free all allocated memory
        exit(1);
    }
    // Some code
    // ...

    // free all allocated memory
    return 0;
}

I want to make cleaning up easier by just invoking a cleanUp() function which will free all the memory allocated in the heap. I want to call this function right before every exit(1) call and before the return 0 line (Essentially replace every comment // free all allocated memory with a call to cleanUp()). My question is that how do I pass the pointers data1,data2,result and buffer to cleanUp() such that they can be freed?

This is what I am thinking to do. Is this the right approach?

void cleanUp(void* p1, void* p2, void* p3, void* p4){
    // call to free for each pointer
}

Solution

  • If you've ever been taught to never use goto, well something like is a prime example of a good time to use goto.

    int main(int argc, char** argv){
        int ret_status = 0;
        // Some code
        // ...
        // ...
        void* data1 = malloc(someSize);
        void* data2 = malloc(someSize);
        double* result = malloc(resultSize);
        double* buffer = malloc(buffSize);
        // allocation failure: first exit point
        if(!(data1 && data2 && result && buffer)){
            ret_status = 1;
            goto cleanup;
        }
        // Some code
        // ...
        // Second exit point
        if(someOtherExitcondition){
            ret_status = 1;
            goto cleanup;
        }
        // Some code
        // ...
    
    cleanup:
        // free all allocated memory     
        free(data1);
        free(data2);
        free(result);
        free(buffer);
    
        return ret_status;
    }
    

    If, unlike the given example, you were also calling exit() from nested functions, look at using atexit() as given in Jonathan Leffler's answer.