Static memory is memory that is defined at compile time and dynamic memory is memory that is defined at run time. Most programmers are aware that static memory allocation takes place on the stack whereas dynamic memory allocation usually takes place on the heap. What isn’t very common knowledge is the fact that memory can be dynamically allocated on the stack too. This however comes with its own benefits and caveats.
C programmers will be familiar with malloc() function which is used to dynamically allocate memory on heap. C language also provides alloca() function which dynamically allocates memory on the stack. Usage of alloca() is the same as malloc(). In following sections we will discuss benefits and caveats of alloca().
Two key benefits of alloca() are automatic memory cleanup and better performance. They are explained below.
To prevent memory leaks, every chunk of memory acquired by calling malloc() should be released by calling free(). In contrast, when memory is acquired by calling alloca() it doesn’t need to be released by calling an equivalent of free. This is because before the function starts executing its instructions, the frame pointer is saved. This stage is called function prolog. Then when the function completes execution the frame pointer is restored, effectively freeing up everything that was allocated on the stack for that function. This last stage is called function epilog. Thus prolog and epilog ensure that memory leaks don’t happen.
Memory allocation on the heap involves walking the heap and searching for a suitable chunk of memory to allocate. Memory allocation on stack involves just updating a CPU register. This is the stack pointer register (ESP on 32-bit and RSP on 64-bit CPUs). This makes alloc() much faster than malloc(). Moreover, since stack memory isn’t paged in and out, it doesn’t suffer from page faults. Memory on heap may encounter page faults which will put a small but noticeable drag on performance.
Some would say the caveat of alloca() don’t necessarily outweigh its benefits. However, it is a very important caveat with practical implications. Stack memory is a lot smaller than heap. Therefore, it is more precious. What this means is that:
- it should be used sparingly and
- it shouldn’t be occupied for too long
Therefore, alloca() is suitable for small amounts of memory used by short-lived functions.
Given its advantages, alloca() is surprisingly little known. That however could be due to legacy reasons from the days when memory came at a premium. Now-a-days with 8GB RAMs in common use and RAM sizes having the potential to go much higher*, certainly programmers can do away with more frequent use dynamic stack memory.
*With the prevalent 64-bit architectures, a program can now potentially address up to 16 exabytes* (i.e. 16 giga-gigabytes) of memory. Most hardware architectures however allow 48-52 bits for addressing rather than all 64 bits. That still means a hefty 281GB – 4503 GB of addressable memory!