I'm working on a C++ library, one of whose functions returns a (freshly allocated) pointer to an array of doubles. The API states that it is the responsibility of the caller to deallocate the memory.
However, that C++ library used to be implemented in C and the function in question allocates the memory with malloc()
. It also assumes that the caller will deallocate that memory with free()
.
Can I safely replace the call to malloc()
with a call to new
? Will the existing client code (that uses free()
break if I do so? All I could find so far was the official documentation of free()
, which states that
If ptr does not point to a block of memory allocated with [malloc, calloc or realloc], it causes undefined behavior.
But I believe this was written before C++ came along with its own allocation operators.
You must use delete operator to deallocate memory when it is allocated by new operator. no, you should use delete[] for new[], and delete for new.
In these cases, even small chunks of storage add up and create a problem. Thus our usable space decreases. This is also called “memory leak”. It may also happen that our system goes out of memory if the de-allocation of memory does not take place at the right time.
Freeing memory twice is undefined behavior, e.g. int * x = malloc(sizeof(int)); *x = 9; free(x); free(x); Quote from standard(7.20. 3.2.
If we allocate memory using malloc, it should be deleted using free. If we allocate memory using new, it should be deleted using delete.
You MUST match calls to malloc
with free
and new
with delete
. Mixing/matching them is not an option.
You are not allowed to mix and match malloc
and free
with new
and delete
the draft C++ standard refers back to the C99 standard for this and if we go to the draft C++ standard section 20.6.13
C library it says (emphasis mine going forward):
The contents are the same as the Standard C library header stdlib.h, with the following changes:
and:
The functions calloc(), malloc(), and realloc() do not attempt to allocate storage by calling ::operator new() (18.6).
and:
The function free() does not attempt to deallocate storage by calling ::operator delete(). See also: ISO C Clause 7.11.2.
and includes other changes, none of which state that we can use free
on contents allocated with new
. So section 7.20.3.2
The free function from the draft C99 standard is still the proper reference and it says:
Otherwise, if the argument does not match a pointer earlier returned by the calloc, malloc, or realloc function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.
As you've heard now, you can't mix them.
Keep in mind that in C++ it's common to have lots of relatively small temporary objects dynamically allocated (for instance, it's easy to write code like my_string + ' ' + your_string + '\n'
), while in C memory allocation's typically more deliberate, often with a larger average allocation size and longer lifetime (much more likely someone would directly malloc(strlen(my_string) + strlen(your_string) + 3)
for the result without any temporary buffers). For that reason, some C++ libraries will optimise for large numbers of small transient objects. They might, for instance, use malloc()
to get three 16k blocks, then use each for fixed-size requests of up to 16, 32 and 64 bytes respectively. If you call delete
in such a situation, it doesn't free anything - it just returns the particular entry in the 16k buffer to a C++-library free list. If you called free()
and the pointer happened to be to the first element in the 16k buffer, you'd accidentally deallocate all the elements; if it wasn't to the first you have undefined behaviour (but some implementations like Visual C++ apparently still free blocks given a pointer anywhere inside them).
So - really, really don't do it.
Even if it ostensibly works on your current system, it's a bomb waiting to go off. Different runtime behaviour (based on different inputs, thread race conditions etc.) could cause a later failure. Compilation with different optimisation flags, compiler version, OS etc. could all break it at any time.
The library should really provide a deallocation function that forwards to the correct function.
In addition to what the others already said (no compatibility guarantee), there is also the possibility that the library is linked to a different C library than your program, and so invoking free()
on a pointer received from them would pass it to the wrong deallocation function even if the function names are correct.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With