Dynamic Memory
Allocation & Fragmentation
in C & C++
Colin Walls
colin_walls@mentor.com
Agenda
▪ Introduction to memory usage
▪ Dynamic memory in C
▪ Dynamic memory in C++
▪ Issues and problems
▪ Memory with an RTOS
▪ Real time memory solutions
▪ Conclusions
2
www.mentor.com/embedded
Agenda
▪ Introduction to memory usage
▪ Dynamic memory in C
▪ Dynamic memory in C++
▪ Issues and problems
▪ Memory with an RTOS
▪ Real time memory solutions
▪ Conclusions
3
www.mentor.com/embedded
C/C++ Memory Spaces
▪ Static memory Static storage
▪ variables outside of Variables
functions
▪ static internal variables
▪ keyword static
RAM address
▪ program sections [FGA]
4
www.mentor.com/embedded
C/C++ Memory Spaces
▪ Static memory Static storage
▪ variables outside of Variables
functions
▪ static internal variables Dynamic storage
▪ keyword static
RAM address
▪ program sections [FGA]
▪ Automatic variables
▪ stack
▪ register
▪ keyword auto
Stack
5
www.mentor.com/embedded
C/C++ Memory Spaces
▪ Static memory Static storage
▪ variables outside of Variables
functions
▪ static internal variables Dynamic storage
▪ keyword static Heap
RAM address
▪ program sections [FGA]
▪ Automatic variables
▪ stack
▪ register
▪ keyword auto
▪ Heap Stack
6
www.mentor.com/embedded
C/C++ Memory Spaces
Static storage
Variables
Dynamic storage
Heap
▪ With an operating
RAM address
system, there are
typically multiple stacks
Stack
Stack
Stack
Stack
7
www.mentor.com/embedded
Agenda
▪ Introduction to memory usage
▪ Dynamic memory in C
▪ Dynamic memory in C++
▪ Issues and problems
▪ Memory with an RTOS
▪ Real time memory solutions
▪ Conclusions
8
www.mentor.com/embedded
Dynamic Memory in C
▪ Management of heap space
▪ Key functions
▪ malloc()
▪ free()
void *malloc(size_t size);
void free(void *pointer);
9
www.mentor.com/embedded
Dynamic Memory in C
int my_array[10];
my_array[3] = 99;
int *pointer;
pointer = malloc(10 * sizeof(int));
*(pointer+3) = 99;
pointer[3] = 99;
...
free(pointer);
pointer = NULL;
10
www.mentor.com/embedded
Dynamic Memory in C
Heap
Size info
Pointer from malloc()
Data space
11
www.mentor.com/embedded
Dynamic Memory in C
▪ Variant functions
▪ calloc()
▪ simpler parameters
▪ initialized to zero
▪ realloc()
▪ copies as necessary
void *calloc(size_t nelements, size_t elementSize);
void *realloc(void *pointer, size_t size);
12
www.mentor.com/embedded
Agenda
▪ Introduction to memory usage
▪ Dynamic memory in C
▪ Dynamic memory in C++
▪ Issues and problems
▪ Memory with an RTOS
▪ Real time memory solutions
▪ Conclusions
13
www.mentor.com/embedded
Dynamic Memory in C++
▪ Same principle as C
▪ Library functions available
▪ New operators more
flexible and less error p_var = new typename;
p_var = new type(initializer);
prone:
p_array = new type [size];
▪ new
▪ delete delete p_var;
▪ care needed to use correct delete[] p_array;
deallocator
▪ No reallocator
▪ Also STL
14
www.mentor.com/embedded
Dynamic Memory in C++
int my_array[10];
my_array[3] = 99;
int* pointer;
pointer = new int[10];
pointer[3] = 99;
...
delete[] pointer;
pointer = NULL;
15
www.mentor.com/embedded
Agenda
▪ Introduction to memory usage
▪ Dynamic memory in C
▪ Dynamic memory in C++
▪ Issues and problems
▪ Memory with an RTOS
▪ Real time memory solutions
▪ Conclusions
16
www.mentor.com/embedded
Issues and Problems
▪ Dynamic behavior is troublesome in real time
embedded systems
▪ Issues:
▪ resource exhaustion
▪ non-determinism
▪ Examples:
▪ dynamic memory
▪ RTOS objects
17
www.mentor.com/embedded
Issues and Problems
▪ Stack overflow/underflow
▪ push too much data
▪ pop when stack empty
▪ hard to locate bug
▪ errors may show up much later
▪ most likely in another task
18
www.mentor.com/embedded
Issues and Problems
▪ malloc() etc.
▪ reentrancy
▪ determinism of allocation time
▪ memory leaks
▪ mismatch of allocation and deallocation
▪ lead to performance degradation over time
▪ allocation failure
▪ what to do?
▪ not enough memory
▪ fragmentation …
19
www.mentor.com/embedded
Memory Fragmentation
Heap [10K]
#define K (1024) p1
... 3K
char *p1;
p1 = malloc(3*K);
[7K free]
20
www.mentor.com/embedded
Memory Fragmentation
Heap [10K]
#define K (1024) p1
... 3K
char *p1, *p2;
p2
p1 = malloc(3*K);
p2 = malloc(4*K); 4K
...
[3K free]
21
www.mentor.com/embedded
Memory Fragmentation
Heap [10K]
#define K (1024)
... [3K free]
char *p1, *p2;
p2
p1 = malloc(3*K);
p2 = malloc(4*K); 4K
...
free(p1);
[3K free]
22
www.mentor.com/embedded
Memory Fragmentation
Heap [10K]
#define K (1024)
... [3K free]
char *p1, *p2;
p2
p1 = malloc(3*K);
p2 = malloc(4*K); 4K
...
free(p1);
[3K free]
p1 = malloc(4*K); //fails!
23
www.mentor.com/embedded
Memory Fragmentation
▪ Defragmentation not possible with direct
pointers
▪ other code using memory address would be broken
▪ Garbage collection performed in other
languages
▪ e.g. Java, BASIC
▪ no direct pointers
▪ not real time
24
www.mentor.com/embedded
Agenda
▪ Introduction to memory usage
▪ Dynamic memory in C
▪ Dynamic memory in C++
▪ Issues and problems
▪ Memory with an RTOS
▪ Real time memory solutions
▪ Conclusions
25
www.mentor.com/embedded
Memory with an RTOS
▪ All OSes provide some memory management
facilities
▪ compatible with real time requirements
▪ deterministic
▪ May offer re-entrant malloc() facility
▪ normally not deterministic
▪ Block/partition memory allocation
26
www.mentor.com/embedded
Block/partition Memory Allocation
▪ Partition pool created ▪ Failure modes limited
either statically or ▪ fragmentation not
dynamically possible
▪ allocation failure
▪ Fixed size blocks of possible
memory ▪ task suspend option
▪ Specified number of ▪ memory leaks possible
blocks
▪ Resource availability
information
27
www.mentor.com/embedded
Block/partition Memory Allocation
STATUS NU_Create_Partition_Pool(NU_PARTITION_POOL *pool,
CHAR *name, VOID *start_address, UNSIGNED pool_size,
UNSIGNED partition_size, OPTION suspend_type)
status = NU_Create_Partition_Pool(&MyPool, “any name”,
(VOID *) 0xB000, 2000, 40, NU_FIFO);
▪ descriptor MyPool
▪ 40 byte partitions
▪ 2000 byte memory area
▪ located at 0xB000
▪ task suspend in FIFO order
28
www.mentor.com/embedded
Block/partition Memory Allocation
status = NU_Allocate_Partition(&MyPool, &ptr, NU_SUSPEND);
▪ allocate a partition from pool described by MyPool
▪ ptr will point to allocated memory
▪ task suspend on allocation failure
status = NU_Deallocate_Partition(ptr);
29
www.mentor.com/embedded
Memory Leak Detection
30
www.mentor.com/embedded
Agenda
▪ Introduction to memory usage
▪ Dynamic memory in C
▪ Dynamic memory in C++
▪ Issues and problems
▪ Memory with an RTOS
▪ Real time memory solutions
▪ Conclusions
31
www.mentor.com/embedded
Stacks
▪ Sizing is a challenge
▪ almost impossible to guard word
assess statically
▪ best measured
dynamically
▪ fill with known value stack
▪ use debugger
trace/coverage
▪ Overflow/underflow SP guard word
▪ can add protection
▪ use guard words or
MMU
32
www.mentor.com/embedded
Dynamic Memory
▪ Define series of partition pools
▪ Geometric series of sizes
▪ e.g. 32, 64, 128, 256 bytes
▪ Write malloc() to select best fit
▪ can be deterministic
▪ Map free() directly on to deallocate API
▪ Failure modes:
▪ no fragmentation
▪ allocation failure causes task suspend
33
www.mentor.com/embedded
Agenda
▪ Introduction to memory usage
▪ Dynamic memory in C
▪ Dynamic memory in C++
▪ Issues and problems
▪ Memory with an RTOS
▪ Real time memory solutions
▪ Conclusions
34
www.mentor.com/embedded
Conclusions
▪ Dynamic behavior, including memory
allocation, is an issue for real time
▪ non-determinism
▪ failure
▪ Fragmentation can be eliminated
▪ Determinism possible
▪ Failure modes can be contained
35
www.mentor.com/embedded
Questions?
Colin Walls
colin_walls@mentor.com
blogs.mentor.com/colinwalls