thecodex.expert · The Codex Family of Knowledge
C++

Memory Management

Mixing new with delete[], or new[] with plain delete, is undefined behavior — a real, genuinely easy mistake, and one more reason modern C++ style avoids writing new/delete directly at all.

C++20 / C++23 Prefer smart pointers over raw new Last verified:
Canonical Definition

new allocates heap memory AND runs the object's constructor in one step; delete runs its destructor AND releases the memory. This is the key difference from C's malloc/free, which are purely memory operations with no awareness of C++ constructors, destructors, or types at all. new[] and delete[] handle arrays specifically and must always be paired with each other — mixing new with delete[], or new[] with plain delete, is undefined behavior. In practice, modern C++ style strongly discourages calling new/delete directly in ordinary code at all, preferring smart pointers (covered in their own topic) and standard containers that manage this automatically.

new and delete: allocation plus construction

Unlike C's malloc, new here actually RUNS Person's constructor on the allocated memory; delete correspondingly runs its destructor before releasing the memory — malloc/free would have no idea Person even had a constructor to call.

C++basic_new_delete.cpp
class Person {
public:
    Person(std::string name) : name_(name) {
        std::cout << "Constructing " << name_ << "\n";
    }
    ~Person() {
        std::cout << "Destructing " << name_ << "\n";
    }
private:
    std::string name_;
};

Person* p = new Person("Alice");   // allocates AND constructs
delete p;                            // destructs AND deallocates

new[] and delete[]: arrays need the matching pair

Mixing these is undefined behavior, not a caught error — the array form tracks the element count somewhere the compiler knows to look, and using the wrong delete form corrupts that bookkeeping.

C++array_new_delete.cpp
int* arr = new int[10];
delete[] arr;   // correct — matches new[]

// int* bad = new int[10];
// delete bad;    // UNDEFINED BEHAVIOR — mismatched with new[]

Why modern C++ avoids writing new/delete directly

Every manual new needs a perfectly-matched delete on every possible code path, including exception paths — genuinely easy to get wrong in anything beyond trivial code. Smart pointers (std::unique_ptr, std::shared_ptr) and standard containers (std::vector, std::string) wrap this exact allocation/deallocation pairing automatically via RAII, which is why idiomatic modern C++ code rarely calls new or delete explicitly at all, reserving them mainly for implementing lower-level building blocks like smart pointers themselves.

Sources

1
ISO/IEC 14882 (C++ Standard), "new expression" and "delete expression," cppreference.com/w/cpp/language/new.