0
0
C++programming~15 mins

delete operator in C++ - Deep Dive

Choose your learning style9 modes available
Overview - delete operator
What is it?
The delete operator in C++ is used to free memory that was previously allocated with the new operator. It tells the program that the memory is no longer needed and can be returned to the system. This helps prevent memory leaks, which happen when memory is reserved but never released. Using delete properly keeps programs efficient and stable.
Why it matters
Without the delete operator, programs would keep using more and more memory without giving it back, causing slowdowns or crashes. It solves the problem of managing memory manually in C++, where automatic cleanup does not happen. This control lets programmers write fast and resource-friendly software, especially important in games, embedded systems, and large applications.
Where it fits
Before learning delete, you should understand how to allocate memory with new and basic pointers. After mastering delete, you can learn about smart pointers that automate memory management and advanced resource handling techniques.
Mental Model
Core Idea
The delete operator tells the program to give back memory that was taken with new, preventing waste and crashes.
Think of it like...
Imagine borrowing a book from a library (new operator). When you finish reading, you return the book (delete operator) so others can use it. Forgetting to return the book means no one else can read it, just like memory leaks block resources.
┌───────────────┐       ┌───────────────┐
│  new allocates│──────▶│ Memory reserved│
└───────────────┘       └───────────────┘
         │                        │
         │                        ▼
         │               ┌───────────────┐
         │               │ delete frees  │
         └──────────────▶│ memory back   │
                         └───────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding dynamic memory allocation
🤔
Concept: Learn how new allocates memory on the heap for variables during runtime.
In C++, new lets you create variables whose size or lifetime you control. For example: int* p = new int(10); This creates an integer on the heap with value 10, and p points to it. This memory stays until you free it.
Result
Memory is reserved on the heap, and p holds its address.
Knowing that new reserves memory outside normal variable scope is key to understanding why delete is needed.
2
FoundationWhy manual memory release is necessary
🤔
Concept: Understand that memory allocated with new stays until explicitly freed.
If you write: int* p = new int(5); and never call delete p;, the memory stays reserved even if p goes out of scope. This causes a memory leak, wasting resources.
Result
Memory leaks happen if delete is not used after new.
Recognizing that C++ does not automatically clean heap memory explains the need for delete.
3
IntermediateUsing delete for single objects
🤔Before reading on: do you think delete p; frees the memory pointed by p and sets p to nullptr automatically? Commit to your answer.
Concept: Learn the syntax and effect of delete on pointers to single objects.
To free memory allocated for one object: int* p = new int(42); delete p; This releases the memory. Note: delete does NOT set p to nullptr automatically; you must do it yourself if needed.
Result
Memory is freed, but p still holds the old address (dangling pointer).
Understanding that delete frees memory but does not change the pointer value helps avoid bugs with dangling pointers.
4
IntermediateUsing delete[] for arrays
🤔Before reading on: do you think delete and delete[] behave the same when freeing arrays? Commit to your answer.
Concept: Learn that arrays allocated with new[] must be freed with delete[].
For arrays: int* arr = new int[5]; delete[] arr; Using delete instead of delete[] here causes undefined behavior because the program won't call destructors properly for each element.
Result
Memory for the entire array is freed safely.
Knowing the difference between delete and delete[] prevents subtle bugs and crashes.
5
IntermediateAvoiding double delete errors
🤔Before reading on: do you think deleting the same pointer twice is safe or causes problems? Commit to your answer.
Concept: Understand that deleting a pointer twice causes runtime errors.
If you do: int* p = new int(10); delete p; delete p; // ERROR The second delete tries to free memory already freed, leading to crashes or undefined behavior.
Result
Program may crash or behave unpredictably.
Recognizing double delete as a common bug helps write safer code by careful pointer management.
6
AdvancedDeleting polymorphic objects safely
🤔Before reading on: do you think delete calls the correct destructor for derived classes if base destructor is not virtual? Commit to your answer.
Concept: Learn that base class destructors must be virtual to delete derived objects safely.
If you have: class Base { ~Base() {} }; class Derived : public Base { ~Derived() {} }; Base* p = new Derived(); delete p; Without a virtual destructor in Base, only Base's destructor runs, causing resource leaks in Derived.
Result
Proper cleanup happens only if Base destructor is virtual.
Understanding virtual destructors is critical for correct memory management in inheritance.
7
ExpertHow delete interacts with operator overloading
🤔Before reading on: do you think you can customize how delete frees memory by overloading operator delete? Commit to your answer.
Concept: Discover that C++ allows customizing delete behavior by overloading operator delete.
C++ lets you define your own operator delete to control memory freeing: void operator delete(void* ptr) { // custom cleanup code free(ptr); } This is used in custom allocators or debugging tools to track memory usage.
Result
Delete calls your custom function, changing how memory is freed.
Knowing operator delete overloading enables advanced memory management and debugging techniques.
Under the Hood
When delete is called on a pointer, the program first calls the destructor of the object pointed to, cleaning up resources inside the object. Then, it returns the memory block to the heap allocator, marking it as free for future use. For arrays, delete[] calls destructors for each element in order before freeing memory. The runtime keeps track of allocated blocks to manage this process.
Why designed this way?
C++ was designed for performance and control, so it separates allocation and deallocation explicitly. This avoids hidden overhead and lets programmers optimize memory use. Automatic garbage collection was avoided to keep programs predictable and fast. Overloading operator delete allows flexibility for different memory management strategies.
┌───────────────┐
│ delete called │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Call destructor│
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Return memory  │
│ to heap system │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does delete automatically set the pointer to nullptr? Commit yes or no.
Common Belief:Delete sets the pointer to nullptr automatically after freeing memory.
Tap to reveal reality
Reality:Delete frees memory but leaves the pointer unchanged, which can become a dangling pointer.
Why it matters:Using a dangling pointer can cause crashes or data corruption if accessed after delete.
Quick: Can you use delete on memory not allocated with new? Commit yes or no.
Common Belief:You can use delete on any pointer, even if it points to stack or static memory.
Tap to reveal reality
Reality:Delete must only be used on pointers from new; using it otherwise causes undefined behavior.
Why it matters:Deleting non-heap memory can crash the program or corrupt memory.
Quick: Does delete call destructors for array elements if you use delete instead of delete[]? Commit yes or no.
Common Belief:Using delete on arrays calls destructors for all elements just like delete[].
Tap to reveal reality
Reality:Using delete on arrays calls destructor only for the first element or none, causing resource leaks.
Why it matters:Improper destructor calls lead to incomplete cleanup and bugs.
Quick: If base class destructor is not virtual, does delete on base pointer call derived destructor? Commit yes or no.
Common Belief:Delete always calls the correct destructor for derived objects, regardless of virtual keyword.
Tap to reveal reality
Reality:Without virtual destructor, only base destructor runs, skipping derived cleanup.
Why it matters:Skipping derived destructors causes resource leaks and undefined behavior.
Expert Zone
1
Overloading operator delete can be paired with operator new to implement custom memory pools or debugging tools.
2
Calling delete on a null pointer is safe and does nothing, which simplifies cleanup code.
3
Placement new allocates memory separately and requires explicit destructor calls without delete.
When NOT to use
Avoid manual delete in modern C++ when possible; prefer smart pointers like std::unique_ptr or std::shared_ptr that automate memory management and prevent leaks and double deletes.
Production Patterns
In production, delete is often wrapped inside RAII classes or smart pointers to ensure exception safety and avoid manual errors. Custom allocators overload operator delete to optimize performance in games or real-time systems.
Connections
Smart pointers
Builds-on
Understanding delete clarifies why smart pointers automate memory release and prevent common bugs.
Garbage collection
Opposite approach
Delete manual memory management contrasts with automatic garbage collection, highlighting tradeoffs between control and convenience.
Library book borrowing
Real-world resource management
Managing memory with new and delete is like borrowing and returning library books, teaching responsibility for shared resources.
Common Pitfalls
#1Forgetting to use delete after new causes memory leaks.
Wrong approach:int* p = new int(5); // no delete called
Correct approach:int* p = new int(5); delete p;
Root cause:Not understanding that heap memory persists until explicitly freed.
#2Using delete instead of delete[] on arrays causes undefined behavior.
Wrong approach:int* arr = new int[3]; delete arr;
Correct approach:int* arr = new int[3]; delete[] arr;
Root cause:Confusing syntax for single objects and arrays.
#3Deleting the same pointer twice leads to crashes.
Wrong approach:int* p = new int(10); delete p; delete p;
Correct approach:int* p = new int(10); delete p; p = nullptr; // no second delete
Root cause:Not tracking pointer state after deletion.
Key Takeaways
The delete operator frees memory allocated with new to prevent leaks and keep programs efficient.
Always match new with delete and new[] with delete[] to avoid undefined behavior.
Delete calls destructors before freeing memory, so virtual destructors are essential for polymorphic classes.
Delete does not change the pointer value; setting pointers to nullptr after delete helps avoid dangling pointers.
Modern C++ encourages using smart pointers to automate delete and reduce manual memory errors.