In C, which is the better practice when it comes to freeing memory returned from functions:
- Provide a “destructor” function that encapsulates the call to free().
- Require users to free() the returned pointer themselves.
For example, to open and close a file we do:
FILE* f = fopen("blah", "w");
fclose(f);
Is this preferable to:
FILE* f = fopen("blah", "w");
fclose(f);
free(f);
Warning: Don’t call free() on a FILE pointer. I only use it a hypothetical implementation here.
And what about cases where local variables are pointed to the returned memory? Is free() harmful here? (or perhaps this should never be done)
FILE f = &fopen("blah", "w");
fclose(&f);
You should never free a file – fclose handles releasing the resources properly. In general, only free pointers that were allocated directly by malloc. Most other pointers will have their own resource-cleanup functions.
That being said, as to your initial question:
I find that providing a destructor function is usually better practice, for three reasons.
1) There are many cases where free is inappropriate, and this might not be obvious to your end user. FILE* is a good case of that – you shouldn’t call
free(f);above…2) If you’re using this in a DLL, depending on the runtimes, having the free functionality encapsulated can work around many, many subtle bugs from mixing runtimes, especially on the Windows platform. Trying to use a DLL compiled in VS2005 from VS2008 can cause problems if you happen to free memory in one platform’s code which was allocated in another. Having a “wrapper” function to handle the memory management works around that significant issue.
3) Many of the C API functions work this way – such as FILE* using fopen/fclose. This will not be surprising to a user of your library.