What is the difference between new/delete and malloc/free?
new
/ delete
- Allocate / release memory
- Memory allocated from 'Free Store'.
- Returns a fully typed pointer.
new
(standard version) never returns aNULL
(will throw on failure).- Are called with Type-ID (compiler calculates the size).
- Has a version explicitly to handle arrays.
- Reallocating (to get more space) not handled intuitively (because of copy constructor).
- Whether they call
malloc
/free
is implementation defined. - Can add a new memory allocator to deal with low memory (
std::set_new_handler
). operator new
/operator delete
can be overridden legally.- Constructor / destructor used to initialize / destroy the object.
malloc
/ free
- Allocate / release memory
- Memory allocated from 'Heap'.
- Returns a
void*
. - Returns
NULL
on failure. - Must specify the size required in bytes.
- Allocating array requires manual calculation of space.
- Reallocating larger chunk of memory simple (no copy constructor to worry about).
- They will NOT call
new
/delete
. - No way to splice user code into the allocation sequence to help with low memory.
malloc
/free
can NOT be overridden legally.
Table comparison of the features:
Feature | new / delete | malloc / free |
---|---|---|
Memory allocated from | 'Free Store' | 'Heap' |
Returns | Fully typed pointer | void* |
On failure | Throws (never returns NULL ) | Returns NULL |
Required size | Calculated by compiler | Must be specified in bytes |
Handling arrays | Has an explicit version | Requires manual calculations |
Reallocating | Not handled intuitively | Simple (no copy constructor) |
Call of reverse | Implementation defined | No |
Low memory cases | Can add a new memory allocator | Not handled by user code |
Overridable | Yes | No |
Use of constructor / destructor | Yes | No |
Why use malloc/free, when we have new/delete?
They're not the same. new
calls the constructor, malloc
just allocates the memory.
Also, it's undefined behavior mixing the two (i.e. using new
with free
and malloc
with delete
).
In C++, you're supposed to use new
and delete
, malloc
and free
are there for compatibility reasons with C.
malloc/free and new/delete compatibility in C++?
Yes, you can interleave them - just use a deallocation function matching the one used for allocation. The problem only arises if you use a wrong deallocation function.
Note that it's not that easy when you have several libraries - those might use different heaps and so even though you use a right named function it might happen to be implemented in the wrong module and so use the wrong heap which will drive you right into undefined behavior. See this answer for a better idea of what I'm talking about here.
Why are new()/delete() slower than malloc()/free()?
Look at this piece of C code:
struct data* pd = malloc(sizeof(struct data));
init_data(pd);
The new
operator in C++ is essentially doing what the above piece of code does. That's why it is slower than malloc()
.
Likewise with delete
. It's doing the equivalent of this:
deinit_data(pd);
free(pd);
If the constructors and destructors are empty (like for built-ins), new
and delete
shouldn't be slower than malloc()
and free()
are. (If they are, it's often due to the fact that common implementations call malloc()
/free()
under the hood, so they are a wrapper around them. Wrapping costs. Also, there might be code that needs to find out that no constructors/destructors are to be called. That would cost, too.)
Edit To answer your additional question:
new
and delete
aren't functions, they are operators. This: new data()
is called a new expression. It does two things. First it calls the operator new
, then it initializes the object, usually by invoking the appropriate constructor. (I say "usually" because built-ins don't have constructors. But a new expression involving a built-in works the same nevertheless.)
You can manipulate both of these phases. You can create your own constructors to manipulate initialization of your types and you can overload operator new
(even with several overloads having different additional arguments and also specifically for each class, if you want) in order to manipulate allocation of free storage. If you don't implement your own operator new
, the version from the standard library is used. A common implementation of this calls malloc()
.
Likewise, if you write delete pd
, called a delete expression, two things happen: depending on pd
, the object is de-initialized, usually by calling its destructor, then the memory is released by calling the appropriate operator delete
.
Again, you can manipulate both phase, by writing your own destructor, and by writing your own version of operator delete
. (The version of operator delete
that comes with your standard library is often implemented to call free()
.)
malloc and free vs new and delete
new
calls a constructor, malloc()
does not. delete
calls a destructor, free()
does not. If the class in question allocates memory internally, then yes, you are likely to encounter a memory leak.
If you have to use malloc()
and free()
(and in C++, you really shouldn't be), you will have to use placement new to call the constructor, and call the destructor yourself, eg:
pStr = static_cast<String*>(malloc(4 * sizeof(String)));
if (pStr)
{
for (int i = 0; i < 4; ++i)
new (&pStr[i]) String;
...
for (int i = 3; i >= 0; --i)
pStr[i].~String();
free(pStr);
}
And if you really need to mimic new[]
, you should handle exceptions thrown by constructors, eg:
pStr = static_cast<String*>(malloc(4 * sizeof(String)));
if (!pStr)
throw std::bad_alloc("");
int numConstructed = 0;
try
{
for (int i = 0; i < 4; ++i)
{
new (&pStr[i]) String;
++numConstructed;
}
}
catch (const std::exception &)
{
for (int i = numConstructed-1; i >= 0; ++i)
pStr[i]).~String();
throw;
}
...
for (int i = numConstructed-1; i >= 0; --i)
pStr[i].~String();
free(pStr);
Any possible use of free() with new & delete with malloc()?
- For one thing, they may be using completely different heaps. In more than one application of ours the global
new
anddelete
are redefined to perform some additional bookkeeping; if you pass tofree
a pointer returned bynew
it won't be recognized as stuff frommalloc
, because we are keeping extra info at the start of each memory block. The standard library can do the same. - Why should there be? As already said, the memory they return can come from different heaps, so it makes no sense to use one to deallocate stuff from the other. Now, if you are allocating POD types and if the global
new
operator is just a thin wrapper aroundmalloc
, in theory it could accidentally work to usefree
for memory allocated withnew
, but I really don't see the point in doing so besides adding confusion (and potential undefined behavior). new
anddelete
were introduced as operators to deal with non-POD types. If all you want is "raw" memorymalloc
(or, in general, a single function) is fine, but if you want to allocate objects stuff gets more complicated; the allocation mechanism must be aware of the type of the allocated data, not just of the required size, because it has to invoke the constructors (the same fordelete
, which has to invoke destructors, althoughnew
could have just saved the function pointer to the destructor).
What if, memory allocated using malloc is deleted using delete rather than free
When you call delete
a pointer, the compiler will call the dtor
of the class for you automatically, but free
won't. (Also new
will call ctor
of the class, malloc
won't.)
In you example, a char array apparently don't have a dtor, so delete does nothing but return the memory. That's why it's okay. (Or vise versa, new a char array and then free it.)
But there can still be a problem: what if new
and malloc
are borrowing memory from different heap manager?
Imagine that, you borrow money from people A, and return to people B later. Even if you are okay with that, have you ever consider A's feeling?
BTW, you should use delete [] pArray;
to free an array allocated using new[]
.
Replace malloc and free by new and delete in a memory pool
Your code is broken and you need to fix it first.
Pre-C++11:
Unions cannot contain a non-static data member with a non-trivial special member function (copy constructor, copy-assignment operator, or destructor).
Post-C++11:
If a union contains a non-static data member with a non-trivial special member function (default constructor, copy/move constructor, copy/move assignment, or destructor), that function is deleted by default in the union and needs to be defined explicitly by the programmer.
See here. You follow neither rule. You need to fix this.
Once you fix it, you can just use node = new MemoryPoolNode()
and delete node;
.
For C++11, this will do:
union MemoryPoolNode
{
MemoryPoolNode *next;
T data;
MemoryPoolNode() : next(NULL) { ; }
~MemoryPoolNode() { ; }
};
new, delete ,malloc & free
If you do so you will run into undefined behavior. Never try that. Although new
might be implemented through malloc()
and delete
might be implemented through free()
there's no guarantee that they are really implemented that way and also the user can overload new
and delete
at his discretion. You risk running into heap corruption.
Other than that don't forget that when you call malloc()
you get raw memory - no constructor is invoked - and when you call free()
no destructor is invoked. This can as well lead to undefined behavior and improper functioning of the program.
The bottom line is... never do this.
Related Topics
Convert Shared Library to Static Library
Using Custom Camera in Opencv (Via Gstreamer)
How to Dynamically Allocate Arrays in C++
Pure-Specifier on Function-Definition
Small String Optimization for Vector
How to Call the Class's Destructor
Clang-Omp in Xcode Under El Capitan
Erase Element in Vector While Iterating the Same Vector
How to Use the Windows API in Mingw
Are Dollar-Signs Allowed in Identifiers in C++03
What Does *& Mean in a Function Parameter
Is Constexpr a "Hint" (Like Inline) or "A Binding Request" to the Compiler
Should I Include Stddef.H or Cstddef for Size_T
How to Get Process Handle from Process Id