Skip to content
C++ Better Explained
Go back
C++ new vs malloc: What's the Difference and Which to Use

C++ new vs malloc: What’s the Difference and Which to Use

Both new and malloc grab memory from the heap, so beginners often assume they’re interchangeable. They’re not. The key difference is that new builds actual C++ objects (it runs constructors), while malloc just hands you a block of raw, uninitialised bytes. In C++, new is almost always the right tool.


The Two in a Nutshell

#include <cstdlib>   // for malloc/free

int main() {
    // C++ style
    int* a = new int(42);   // allocates AND initialises to 42
    delete a;               // frees AND (for objects) runs the destructor

    // C style
    int* b = (int*)malloc(sizeof(int));   // allocates raw memory only
    *b = 42;                              // you must initialise it yourself
    free(b);                              // frees the raw memory

    return 0;
}

Right away you can see three differences: new knows the type, new can initialise the value in the same step, and new is paired with delete rather than free.


Difference 1: Constructors and Destructors

This is the big one. new calls the constructor of a class; malloc does not. For a plain int that doesn’t matter, but for an object it’s everything.

#include <iostream>
#include <cstdlib>
using namespace std;

struct Player {
    string name;
    Player() {
        name = "Unnamed";
        cout << "Player constructed\n";
    }
};

int main() {
    Player* p1 = new Player();   // prints "Player constructed"
    delete p1;                   // runs the destructor

    // malloc skips the constructor entirely:
    Player* p2 = (Player*)malloc(sizeof(Player));
    // p2->name is NOT properly constructed — using it is undefined behaviour!
    free(p2);
    return 0;
}

With malloc, the Player’s string name member is never constructed, so touching it can crash your program. new is safer because it guarantees the object is fully built before you use it.


Difference 2: Type Safety

new returns a pointer of the exact type you asked for. malloc returns void*, which you have to cast yourself.

int* a = new int;              // already an int*
int* b = (int*)malloc(sizeof(int));   // must cast the void*

The cast is easy to get wrong, and a wrong cast compiles happily and then misbehaves at runtime. Fewer casts means fewer bugs.

If you're looking to go deeper with C++, the C++ Better Explained Ebook is perfect for you — whether you're a complete beginner or looking to solidify your understanding. Just $19.

Difference 3: Size Calculation

With new, the compiler works out how many bytes to allocate. With malloc, you compute the size by hand — and forgetting sizeof or getting a count wrong is a classic bug.

int* arr1 = new int[10];                    // compiler knows: 10 ints
int* arr2 = (int*)malloc(10 * sizeof(int)); // you must spell it out

Remember to release array memory the matching way: delete[] arr1; for the new[] version and free(arr2); for the malloc version.


Difference 4: What Happens on Failure

If allocation fails, the two behave differently:

int* p = (int*)malloc(sizeof(int));
if (p == nullptr) {
    // handle failure yourself
}

Forgetting that null check is another way malloc code goes wrong quietly.


Never Mix Them

Because new/delete and malloc/free use different internal bookkeeping, you must pair them correctly:

int* a = new int;
free(a);        // WRONG — undefined behaviour

int* b = (int*)malloc(sizeof(int));
delete b;       // WRONG — undefined behaviour

Always match new with delete, new[] with delete[], and malloc with free.


Side-by-Side Summary

Featurenewmalloc
LanguageC++ operatorC library function
Calls constructor?YesNo
Return typeexact type (e.g. int*)void* (needs cast)
Size calculationautomaticmanual sizeof
On failurethrows bad_allocreturns nullptr
Paired withdelete / delete[]free

Which Should You Use?

In modern C++, prefer new over malloc for anything object-shaped, because it initialises properly and is type-safe. And whenever you can, go one step further and use smart pointers (std::unique_ptr, std::shared_ptr) so memory is freed automatically and you never leak. Reserve malloc for talking to C libraries or the rare case where you truly want raw, uninitialised memory.



Take Your C++ Further

If you’re looking to go deeper with C++, the C++ Better Explained Ebook is perfect for you — whether you’re a complete beginner or looking to solidify your understanding. Just $19.

👉 Get the C++ Better Explained Ebook — $19

📋

Free Download: The 10 Mistakes Every C++ Beginner Makes

A free 1-page checklist that shows the exact traps that slow down every C++ beginner — so you can avoid them from day one.

🔒 No spam. Unsubscribe anytime.


Share this post on:

Written by

Sahil Bora

Software Engineer. Author and creator of C++ Better Explained.


Previous Post
C++ float vs double: Which One Should You Use?
Next Post
C++ priority_queue: A Beginner's Guide with Examples

Keep Learning