I see in C++ there are multiple ways to allocate and free data and I understand that when you call malloc
you should call free
and when you use the
There are a few things which new
does that malloc
doesn’t:
new
constructs the object by calling the constructor of that objectnew
doesn’t require typecasting of allocated memory.So, if you use malloc
, then you need to do above things explicitly, which is not always practical. Additionally, new
can be overloaded but malloc
can’t be.
Rare case to consider using malloc/free instead of new/delete is when you're allocating and then reallocating (simple pod types, not objects) using realloc as there is no similar function to realloc in C++ (although this can be done using a more C++ approach).
From the C++ FQA Lite:
[16.4] Why should I use new instead of trustworthy old malloc()?
FAQ: new/delete call the constructor/destructor; new is type safe, malloc is not; new can be overridden by a class.
FQA: The virtues of new mentioned by the FAQ are not virtues, because constructors, destructors, and operator overloading are garbage (see what happens when you have no garbage collection?), and the type safety issue is really tiny here (normally you have to cast the void* returned by malloc to the right pointer type to assign it to a typed pointer variable, which may be annoying, but far from "unsafe").
Oh, and using trustworthy old malloc makes it possible to use the equally trustworthy & old realloc. Too bad we don't have a shiny new operator renew or something.
Still, new is not bad enough to justify a deviation from the common style used throughout a language, even when the language is C++. In particular, classes with non-trivial constructors will misbehave in fatal ways if you simply malloc the objects. So why not use new throughout the code? People rarely overload operator new, so it probably won't get in your way too much. And if they do overload new, you can always ask them to stop.
Sorry, I just couldn't resist. :)
If you work with data that doesn't need construction/destruction and requires reallocations (e.g., a large array of ints), then I believe malloc/free is a good choice as it gives you realloc, which is way faster than new-memcpy-delete (it is on my Linux box, but I guess this may be platform dependent). If you work with C++ objects that are not POD and require construction/destruction, then you must use the new and delete operators.
Anyway, I don't see why you shouldn't use both (provided that you free your malloced memory and delete objects allocated with new) if can take advantage of the speed boost (sometimes a significant one, if you're reallocing large arrays of POD) that realloc can give you.
Unless you need it though, you should stick to new/delete in C++.
Use malloc
and free
only for allocating memory that is going to be managed by c-centric libraries and APIs. Use new
and delete
(and the []
variants) for everything that you control.
There is one big difference between malloc
and new
. malloc
allocates memory. This is fine for C, because in C, a lump of memory is an object.
In C++, if you're not dealing with POD types (which are similar to C types) you must call a constructor on a memory location to actually have an object there. Non-POD types are very common in C++, as many C++ features make an object automatically non-POD.
new
allocates memory and creates an object on that memory location. For non-POD types this means calling a constructor.
If you do something like this:
non_pod_type* p = (non_pod_type*) malloc(sizeof *p);
The pointer you obtain cannot be dereferenced because it does not point to an object. You'd need to call a constructor on it before you can use it (and this is done using placement new
).
If, on the other hand, you do:
non_pod_type* p = new non_pod_type();
You get a pointer that is always valid, because new
created an object.
Even for POD types, there's a significant difference between the two:
pod_type* p = (pod_type*) malloc(sizeof *p);
std::cout << p->foo;
This piece of code would print an unspecified value, because the POD objects created by malloc
are not initialised.
With new
, you could specify a constructor to call, and thus get a well defined value.
pod_type* p = new pod_type();
std::cout << p->foo; // prints 0
If you really want it, you can use use new
to obtain uninitialised POD objects. See this other answer for more information on that.
Another difference is the behaviour upon failure. When it fails to allocate memory, malloc
returns a null pointer, while new
throws an exception.
The former requires you to test every pointer returned before using it, while the later will always produce valid pointers.
For these reasons, in C++ code you should use new
, and not malloc
. But even then, you should not use new
"in the open", because it acquires resources you need to release later on. When you use new
you should pass its result immediately into a resource managing class:
std::unique_ptr<T> p = std::unique_ptr<T>(new T()); // this won't leak