Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to free() memory allocated by new? [duplicate]

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.

like image 273
lindelof Avatar asked Mar 14 '14 13:03

lindelof


People also ask

Can you free memory allocated with new?

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.

What happens if memory is not freed correctly?

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.

Can you free memory twice?

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.

What will happen if I allocate memory using malloc and free it using free or allocate using new and free it using Delete?

If we allocate memory using malloc, it should be deleted using free. If we allocate memory using new, it should be deleted using delete.


4 Answers

You MUST match calls to malloc with free and new with delete. Mixing/matching them is not an option.

like image 64
edtheprogrammerguy Avatar answered Oct 22 '22 04:10

edtheprogrammerguy


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.

like image 33
Shafik Yaghmour Avatar answered Oct 22 '22 04:10

Shafik Yaghmour


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.

like image 45
Tony Delroy Avatar answered Oct 22 '22 03:10

Tony Delroy


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.

like image 1
Simon Richter Avatar answered Oct 22 '22 04:10

Simon Richter