Memory pool (fixed-size block allocator) in Embedded C - Time & Space Complexity
We want to understand how the time to allocate or free memory changes as the number of blocks grows.
How does the allocator's speed behave when managing many fixed-size blocks?
Analyze the time complexity of the following code snippet.
// Simple fixed-size block allocator
void* mem_alloc() {
if (free_list == NULL) return NULL; // no free blocks
void* block = free_list; // take first free block
free_list = *(void**)free_list; // update free list head
return block;
}
void mem_free(void* block) {
*(void**)block = free_list; // add block back to free list
free_list = block;
}
This code manages a list of free memory blocks. Allocation takes the first free block, and freeing adds a block back to the list.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Access and update a pointer to the head of the free list.
- How many times: Each allocation or free does this once, no loops or recursion involved.
Each allocation or free operation does a fixed number of steps regardless of how many blocks exist.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 2-3 pointer steps |
| 100 | 2-3 pointer steps |
| 1000 | 2-3 pointer steps |
Pattern observation: The number of steps stays the same no matter how many blocks are managed.
Time Complexity: O(1)
This means allocation and freeing take the same short time no matter how many blocks are in the pool.
[X] Wrong: "Allocation time grows as more blocks are used because the list gets longer."
[OK] Correct: The allocator always takes the first free block directly, so it does not search through the list.
Understanding fixed-time memory operations shows you can reason about efficient resource management, a key skill in embedded systems and performance-critical code.
"What if the allocator searched the free list to find a block of a certain size? How would the time complexity change?"
Practice
What is the main advantage of using a memory pool with fixed-size blocks in embedded systems?
Solution
Step 1: Understand memory pool purpose
A memory pool divides memory into fixed-size blocks to allocate memory quickly without fragmentation.Step 2: Identify advantage in embedded systems
Embedded systems need fast and predictable memory allocation, which memory pools provide.Final Answer:
Faster and predictable memory allocation -> Option CQuick Check:
Memory pool advantage = Faster and predictable memory allocation [OK]
- Confusing memory pools with dynamic resizing
- Thinking memory pools provide garbage collection
- Assuming memory pools allow unlimited memory
Which of the following is the correct way to declare a fixed-size memory pool array for 10 blocks of 32 bytes each in C?
?Solution
Step 1: Understand array dimensions
We want 10 blocks, each block is 32 bytes, so array should be 10 rows and 32 columns.Step 2: Match declaration syntax
char pool[10][32]; declares 10 blocks of 32 bytes each correctly.Final Answer:
char pool[10][32]; -> Option AQuick Check:
Array size = 10 blocks x 32 bytes [OK]
- Swapping dimensions (32 and 10)
- Using pointer array instead of fixed blocks
- Declaring a single large array without blocks
Given this simplified memory pool allocator code snippet, what will be the output?
char pool[3][16];
int free_blocks = 3;
char* allocate() {
if (free_blocks > 0) {
return pool[--free_blocks];
}
return NULL;
}
int main() {
char* p1 = allocate();
char* p2 = allocate();
char* p3 = allocate();
char* p4 = allocate();
printf("%p %p %p %p\n", p1, p2, p3, p4);
return 0;
}Solution
Step 1: Trace allocation calls
Initially free_blocks=3. Each allocate() call decrements free_blocks and returns pool[free_blocks]. So p1=pool[2], p2=pool[1], p3=pool[0], p4=NULL because free_blocks=0.Step 2: Understand output
First three pointers are valid addresses, last pointer is NULL.Final Answer:
Three valid pointers and one NULL pointer -> Option AQuick Check:
3 blocks allocated, 4th returns NULL [OK]
- Assuming pointers are all NULL
- Thinking pointers point to same block
- Forgetting to decrement free_blocks
Identify the bug in this memory pool free function and select the correct fix.
void free_block(char* block) {
if (free_blocks < MAX_BLOCKS) {
pool[free_blocks++] = block;
}
}Solution
Step 1: Analyze free_block logic
The pool array holds actual memory blocks, not pointers. Storing a pointer in pool overwrites data.Step 2: Correct way to free block
Freeing should mark the block as available in a separate structure or use a free list, not overwrite pool data.Final Answer:
Store pointer in pool array is wrong; should mark block as free differently -> Option DQuick Check:
Freeing must not overwrite pool memory [OK]
- Overwriting pool memory with pointers
- Not checking block validity
- Assuming pool holds pointers, not blocks
You want to implement a memory pool that supports 5 blocks of 64 bytes each. You also want to track which blocks are free using a bitmap (an integer where each bit represents a block's status: 0 = free, 1 = used). Which of the following code snippets correctly initializes the bitmap and allocates a block?
?Solution
Step 1: Understand bitmap meaning
Bitmap bit 0 means free, 1 means used. So initializing bitmap=0 means all blocks free.Step 2: Check allocation logic
Allocation finds first free bit (0), sets it to 1 (used), and returns that block.Final Answer:
Bitmap initialized to 0; allocate sets bit to 1 on allocation -> Option BQuick Check:
0 = free, set bit to 1 when used [OK]
- Initializing bitmap with all bits set (all used)
- Checking wrong bit condition for free blocks
- Setting bits incorrectly on allocation
Ready to prove it?
Pass the test and this pattern moves unknown
