Dynamic Memory Allocation (new & delete)

cardimg

In C, we use malloc() and free() to allocate memory on the Heap at runtime.

In C++, we use new and delete.

While they serve the same purpose (runtime allocation), new is strictly superior for objects because:

  1. new allocates memory AND calls the Constructor (initializes the object).
  2. delete calls the Destructor (cleans up resources) AND frees memory.
  3. malloc only allocates raw bytes; it knows nothing about objects.

Syntax & Usage

1. allocating a Single Variable

// C-Style (Bad for Objects)
int* p = (int*)malloc(sizeof(int));
*p = 10;
free(p);

// C++ Style
int* p = new int(10);  // Allocates int, initializes to 10
delete p;              // Destroys and frees

2. Allocating an Array

Use the [] syntax for both allocation and deallocation.

int* buffer = new int[50]; // Allocates array of 50 ints

// ... use buffer ...

delete[] buffer;           // ⚠️ Must use [] to free arrays!

3. Placement New (The Embedded Special)

Allows you to "construct" an object at a specific, pre-allocated memory address (like a static buffer or hardware address) without using the Heap.

uint8_t memory_pool[sizeof(Sensor)]; // Static buffer
Sensor* s = new (memory_pool) Sensor(); // Construct object IN buffer

Memory Layout (Stack vs. Heap)

FeatureStackHeap
AllocationAutomatic (variables inside functions).Manual (new / malloc).
SpeedExtremely Fast (CPU instruction).Slow (Search for free block).
LifetimeEnds when function returns.Persists until delete.
RiskStack Overflow (recursion).Fragmentation & Leaks.

Relevance in Embedded/Firmware

1. The "Avoid" Rule

In strict real-time or safety-critical firmware (automotive, aerospace, medical), Heap allocation is often banned.

  • Reason 1: Fragmentation. Allocating/freeing different sizes creates "holes" in RAM. Eventually, new fails even if total free RAM is sufficient.
  • Reason 2: Non-Determinism. malloc involves searching a list of free blocks. This can take 10 cycles or 10,000 cycles. You cannot predict it.

2. The Exception: Initialization Phase

Some systems allow new only during startup (before the while(1) loop) to configure drivers or buffers based on config files, but never call delete. This avoids fragmentation while allowing flexible configuration.

3. Placement New

This is widely used in C++ kernels (like standard generic drivers) to initialize objects at specific memory addresses (e.g., placing a UART object directly onto the hardware register map).

Common Pitfalls (Practical Tips)

PitfallDetails
❌ Memory LeaksForgetting delete causes the Heap to run out of memory. In firmware, this usually means a system crash after a few hours/days.
❌ Mismatched DeletionAllocating with new[] but freeing with delete (no brackets) is Undefined Behavior. It often corrupts the heap manager.
❌ Use After Free

Accessing a pointer after calling delete on it.

Fix: Always set pointer to nullptr after deletion: delete p; p = nullptr;

❌ FragmentationFrequent new/delete of small objects (strings, temporary buffers) will fragment RAM, leading to allocation failure.
✅ Smart PointersIn modern C++ (if Heap is allowed), prefer Smart Pointers (std::unique_ptr) which call delete automatically when the pointer goes out of scope.

 

 

 

Concept understood? Let's apply and learn for real

Practice now