Before smart pointers (capable of taking ownership of resources in the dynamic region and freeing them after use) came into being, I wonder how bookkeeping on dynamically created objects was performed when passed as arguments to functions that took resource pointers.
By bookkeeping, I mean that if there is a "new" then at some point later there should be a "delete" following it. Otherwise, the program will suffer from a memory leak.
Here is an example with B being a class and void a_function(B*) being a third party library function:
void main() {
B* b = new B(); // line1
a_function(b); // line2
??? // line3
}
What do I do in line 3? Do I assume that the third party function has taken care of de-allocating the memory? If it has not and I assume that it has, then my program suffers from a memory leak. But, if it de-allocates the memory occupied by b and I too do it in main() so as to be on the safe side, then b actually ends up being freed twice! My program will crash due to a double-free error!
Okay, staying off the impending discussion of why this isn't relevant and you should be using smart pointers anyway...
All other things being equal (no custom allocators or anything fancy like that) the rule is whoever allocates the memory should deallocate the memory. Third-party functions, such as that in your example, should absolutely never be deallocating memory that it didn't create, mainly because 1) it's bad practice in general (terrible code smell) and more importantly 2) it doesn't know how the memory was allocated to start with. Imagine the following:
int main()
{
void * memory = malloc(sizeof(int));
some_awesome_function(memory);
}
// meanwhile, in a third-party library...
void some_awesome_function(void * data)
{
delete data;
}
What happens if malloc/free
and new/delete
are operating using different allocators? You're looking at a potential error of some sort because the allocator used for delete
has no idea what to do with memory that was allocated by malloc
's allocator. You never free
memory that was new
'd, and you never delete
memory that was malloc
'd. Ever.
As for the first point, the fact that you have to ask what would happen if a third-party library deallocated memory and you tried to (or didn't try to) manually free it is exactly why things shouldn't be done that way: because you simply have no way of knowing. So, it's accepted practice that whatever portion of code is responsible for allocation is also responsible for deallocation. If everyone sticks to this rule, everyone can keep track of their memory and nobody is left guessing.