Question.8
A firmware architect allows new only during initialization, never inside the main loop. Why is this acceptable?
void system_init() {
uart_buf = new uint8_t[UART_BUF_SIZE];
sensor = new Sensor(I2C_BUS);
}
int main() {
system_init();
while (true) { /* NEVER call new/delete here */ }
}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:
new allocates memory AND calls the Constructor (initializes the object).delete calls the Destructor (cleans up resources) AND frees memory.malloc only allocates raw bytes; it knows nothing about objects.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 frees2. 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| Feature | Stack | Heap |
|---|---|---|
| Allocation | Automatic (variables inside functions). | Manual (new / malloc). |
| Speed | Extremely Fast (CPU instruction). | Slow (Search for free block). |
| Lifetime | Ends when function returns. | Persists until delete. |
| Risk | Stack Overflow (recursion). | Fragmentation & Leaks. |
1. The "Avoid" Rule
In strict real-time or safety-critical firmware (automotive, aerospace, medical), Heap allocation is often banned.
new fails even if total free RAM is sufficient.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).
| Pitfall | Details |
|---|---|
| ❌ Memory Leaks | Forgetting delete causes the Heap to run out of memory. In firmware, this usually means a system crash after a few hours/days. |
| ❌ Mismatched Deletion | Allocating 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 Fix: Always set pointer to |
| ❌ Fragmentation | Frequent new/delete of small objects (strings, temporary buffers) will fragment RAM, leading to allocation failure. |
| ✅ Smart Pointers | In modern C++ (if Heap is allowed), prefer Smart Pointers (std::unique_ptr) which call delete automatically when the pointer goes out of scope. |