In this tutorial, you will learn the difference between malloc() and operator new ( malloc vs new). Both new and malloc() are used for dynamic memory allocation. But they are different from each other.
The primary difference between new and malloc is that new is an operator and returns a type-safe pointer to initialized memory block whereas malloc is a standard library function that returns a void pointer (not type-safe) to an uninitialized memory block. Let’s see some differences between malloc and new.
Following are the differences between malloc() and operator new (malloc vs new):
1. Constructors:
The class constructor is invoked by the new operator but not by the malloc. You can also initialize the primitive data types (char, int, float.. etc) using the initializer of new expression. See the below examples.
Example 1:
In the below example constructing a class object using the new expression and destroying it using the delete expression. I have printed the message in constructor and destructor, you can see the output.
#include <iostream> using namespace std; class Animal { public: unsigned int m_uiSpeed; Animal(); ~Animal(); }; // constructor Animal::Animal() { cout<<"\nCreating Object\n"; } // destructor Animal::~Animal() { cout<<"\nDeleting Object\n"; } int main() { //Creating object using new operator Animal *cat = new Animal(); delete cat; return 0; }
Output:
Example 2:
In the below example with the help of the new operator, we are allocating the memory for the integer and initializing the allocated memory.
#include<iostream> using namespace std; int main() { // Initialization with new() int *ptr = new int(27); cout << *ptr << endl; delete ptr; return 0; }
Output: 27
2. function vs operator:
The malloc() is a library function that takes a number (of bytes) as its argument returns a void* pointing to uninitialized storage.
Syntax of malloc:
//Syntax of malloc function void *malloc(size_t size); where, size is number of bytes to allocate
Example,
In the below example, you can see I have explicitly typecast the void * to int*
. If I will not do it I will get the compiler error “error: invalid conversion from ‘void*’ to ‘int*'”. Some time explicit typecast is dangerous and becomes the source of hidden bugs.
#include <iostream> #include <cstdlib> using namespace std; int main() { // allocate memory of int size to an int pointer // Also explicitly need to typecast int* ptr = (int*) malloc(sizeof(int)); // assign the value 5 to allocated memory *ptr = 5; cout << *ptr; free(ptr); return 0; }
The new is an operator that takes a type and a set of initializers(optionally) for that type as its arguments and returns a pointer to an (optionally) initialized object of its type.
Example,
You can see the below example, in which we have allocated memory for the integer and we don’t need to typecast the pointer explicitly.
#include <iostream> using namespace std; int main() { // allocate memory and explicit typecast not require int *ptr = new int; // assign the value 5 to allocated memory *ptr = 5; cout << *ptr; delete ptr; return 0; }
3. Type safety:
The malloc() returns a void*
which is not type-safe. new T
returns a pointer to T. You can check the above examples I have already explained.
4. On failure:
On failure, malloc() returns NULL, whereas new throws bad_alloc exception. If you will use nothrow
, new will return a null pointer on failure.
Example,
// throws bad_alloc if it fails T* p1 = new T; // returns nullptr if it fails T* p2 = new(nothrow) T;
5. Required size:
The required size of memory is calculated by the compiler for new, whereas we have to manually calculate the size for malloc().
Example,
// allocate memory using new and // does not need to calculate the size of int int *ptr1 = new int; // allocate memory using malloc() and // need to calculate the size of int using the sizeof int *ptr2 = (int*)malloc(sizeof int);
6. Handling arrays:
Allocating an array requires the manual calculation of space with malloc whereas it is not required with the new. Whenever you use malloc() you have to verify the number of bytes, it must be right for your use.
Example,
// allocate memory for an array of 10 int using new. // does not require any calculation. int *ptr1 = new int[10]; // allocate memory for an array of 10 int using malloc(). // require calculation. int *ptr2 = (int*)malloc(sizeof(int) * 10);
7. Overridability:
“new” is an operator that can be overridden by a class, while malloc() is not overridable on a per-class basis.
8. Deallocation:
Objects created by new are destroyed by delete.
Example,
int *ptr1 = new int; //use of ptr1 delete ptr1
Memory allocated by malloc() is deallocated by free().
int *ptr2 = (int*)malloc(sizeof(int)); //use of ptr2 free(ptr2);
Now let’s see the differences between malloc and new in the below-mentioned comparison chart.
Comparison chart for malloc and new (malloc vs new):
Feature | new |
malloc |
---|---|---|
Supported language | C++ specific features | Supported by both C and C++ |
Type | new is an operator that takes a type and (optionally) a set of initializers for that type as its arguments. |
malloc() is a library function that takes a number (of bytes) as its argument. |
Returns | Returns a pointer to an (optionally) initialized object of its type which is type-safe. | It returns a void* pointing to uninitialized storage which is type unsafe. |
On failure | It throws bad_alloc exception on failure. | Returns NULL |
Required size | Calculated by compiler | Must be specified in bytes |
Handling arrays | Has an explicit version | Requires manual calculations |
Use of constructor | Yes. Operator new call the constructor of an object. | No |
Overridable | Yes. | No |
Deallocation | memory allocated by malloc() is deallocated by free(). | Objects created by new are destroyed by delete. |
Initialization | The operator new could initialize an object while allocating memory to it. | The malloc returns an uninitialized block of memory. |