Skip to content
Dynamic Memory: new and delete
step 1/7

Reading — step 1 of 7

Learn

~2 min readPointers and Memory

C++ programs allocate memory in two places:

  • The stack — automatic variables, function parameters. Fast (just a pointer bump). Limited size (~1 MB typical). Variables die when their scope ends.
  • The heap — explicit allocations via new. Larger pool. YOU manage the lifetime — must delete what you new'd, or memory leaks.
void stackExample() {
    int x = 5;             // on the stack
    int arr[1000];          // on the stack — careful, 1MB stack limit
}   // x and arr automatically destroyed

void heapExample() {
    int* p = new int(42);   // heap allocation, initialized to 42
    std::cout << *p;
    delete p;                // explicit free — pointer is now dangling
    // *p = 5;                // undefined behavior — already freed
}

new returns a pointer to a heap-allocated object. delete frees it. Forgetting delete is a memory leak. Calling delete twice is undefined behavior. Calling delete on a non-heap pointer is undefined behavior.

Heap arrays

For arrays:

int* arr = new int[100];     // 100 ints on the heap, uninitialized
arr[0] = 1;
arr[99] = 99;
delete[] arr;                 // note the [] — different from regular delete

Array new requires array delete[]. Mismatch is undefined behavior. Modern code prefers std::vector for dynamic arrays (handles all this for you).

When to use new (rarely, in modern C++)

In modern C++, you almost never write raw new. Reasons:

  1. Manual memory management is error-prone — leaks, double-frees, dangling pointers.
  2. Smart pointers (next lesson) handle ownership automatically.
  3. STL containers manage heap memory internally.
// Old way (error-prone):
std::string* p = new std::string("hello");
// ... lots of code ... did everyone remember to delete?
delete p;

// Modern way (RAII):
auto p = std::make_unique<std::string>("hello");
// p auto-deletes when it goes out of scope

// For dynamic arrays:
std::vector<int> v(100);   // handles allocation and freeing for you

Use new only for:

  • Educational purposes (this lesson)
  • Implementing smart pointers / containers
  • Interop with C APIs that take ownership of raw pointers

What's actually on the heap?

When you write new T(args), the runtime:

  1. Asks the OS for sizeof(T) bytes of heap memory.
  2. Calls T's constructor in that memory.
  3. Returns a pointer to it.

When you write delete p:

  1. Calls T's destructor on *p.
  2. Returns the memory to the OS allocator.

Common mistakes

  • Forgetting delete → memory leak. Heap memory persists until process exits or you free it.
  • Calling delete twice → double-free → corruption + undefined behavior. Use smart pointers to avoid.
  • Dereferencing after delete → use-after-free → undefined behavior.
  • Mixing new with free or malloc with delete → undefined behavior. They're incompatible.
  • Mixing new T with delete[] p (or vice versa) → undefined behavior.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…