Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The delete operator is a unary operator used to deallocate memory that was previously allocated dynamically on the free store (heap) using the new operator. It destroys the object at the specified memory address and returns the memory to the system, preventing memory leaks.

Syntax

The operator has two distinct forms depending on how the memory was originally allocated:
// Scalar form: Deallocates memory for a single object
delete pointer;

// Array form: Deallocates memory for an array of objects
delete[] pointer;

Execution Mechanics

When the delete operator is invoked, it executes a strict two-step process:
  1. Destruction: It invokes the destructor of the object (or, in the case of delete[], the destructors of every object in the array in reverse order of their construction). This allows the object to safely release any internal resources.
  2. Deallocation: It calls the underlying memory deallocation function (operator delete or operator delete[]) to return the raw memory bytes to the free store.

Technical Rules and Undefined Behavior

To maintain memory safety, the delete operator is governed by strict rules. Violating these rules typically results in undefined behavior (UB):
  • Null Pointers: Applying delete or delete[] to a nullptr is a guaranteed no-operation. It is inherently safe and requires no explicit null-check prior to invocation.
  • Form Matching: The scalar delete must strictly pair with the scalar new. The array delete[] must strictly pair with the array new[]. Mismatching these forms (e.g., using delete on a pointer allocated with new[]) causes UB.
  • Double Free: Invoking delete on a memory address that has already been deallocated results in UB.
  • Non-Dynamic Memory: Applying delete to a pointer referencing memory not allocated by new (such as stack-allocated variables or statically allocated memory) results in UB.
  • Polymorphic Deletion: If delete is applied to a base class pointer that points to a derived class object, the base class must have a virtual destructor. If the base class destructor is not virtual, the invocation results in UB (typically failing to call the derived class’s destructor, resulting in resource leaks).
  • Incomplete Types: Applying delete to a pointer of an incomplete class type results in UB if the fully defined class ultimately possesses a non-trivial destructor or a class-specific operator delete.

Dangling Pointers

After the delete operator completes execution, the pointer variable itself continues to exist in its current scope and retains the now-invalid memory address. This is known as a dangling pointer. Dereferencing a dangling pointer results in UB.
int* ptr = new int(5);
delete ptr; 
// ptr is now a dangling pointer. 
// ptr = nullptr; // Recommended practice to prevent accidental dereferencing

Overloading operator delete

While the delete operator itself (the two-step process of destruction and deallocation) cannot be overloaded, the underlying deallocation function (operator delete) can be overloaded either globally or at the class scope to implement custom memory management strategies.
// Global or class-specific overload signatures
void operator delete(void* ptr) noexcept;
void operator delete[](void* ptr) noexcept;

// C++14 introduced sized deallocation overloads
void operator delete(void* ptr, std::size_t sz) noexcept;
void operator delete[](void* ptr, std::size_t sz) noexcept;
Master C++ with Deep Grasping Methodology!Learn More