Memory Allocation via Malloc, Alloca, etc

CS 301 Lecture, Dr. Lawlor

Allocating Space for an Array

There are many ways to allocate space for an array in C or C++:
There are also many ways to do this in assembly.  The most common way is to call malloc and free.  "malloc" is a C function that takes one parameter, the number of bytes to allocate, and returns a pointer to the allocated memory.  Here's how you call "malloc" in assembly:
push 4*10; Number of bytes to allocate
extern malloc
call malloc
add esp,4; Undo "push"
; Malloc's return value, a pointer, comes back in eax.
... ; use eax as array here
; Eventually, you'll need to call "free" to release that memory:
push eax
extern free
call free
add esp,4; Undo "push"
(executable NetRun link)

Stack Allocation

You can also allocate space on the stack, by just moving the stack pointer down to make room:
sub esp,4*10; Make space on the stack
mov eax, esp; Point eax to the start of that space
... ; Use eax as array here
add esp,4*10; Restore stack
C/C++ of course can't directly access the stack pointer, but there's often a compiler-builtin function called "alloca" (which looks suspiciously like malloc!) that allocates a user-defined amount of space on the stack.  Unlike malloc, memory allocated with alloca is automatically freed when the function returns.  "alloca" may not exist on all machines, since some machines have rather funky stacks.

Fixed Allocation

Finally, you can allocate space in the initialized (".data") or uninitialized (".bss") section of your executable file:
mov eax,thingy; Point eax to thingy's data

section .bss; <- Uninitialized (but writeable!) data area
resb 4*10; Reserve this many bytes of space here

Any of these allocation schemes will work, and the pointer you end up with is just plain old memory.  But there are tradeoffs in deciding which memory allocation scheme to use.  Malloc is slow and a pain to use, but offers the most possible memory (gigabytes).  The stack is very fast, but must be given back at the end of your subroutine, and is limited to a few megabytes on many machines.  Initialized or uninitialized data is a fixed size, and always allocated; this is a waste of space unless you're storing small objects of a few kilobytes.

Assembly Example
Slow (100ns)
push 100
call malloc
Must remember to call free
stack or alloca
Fast (1ns)
sub esp,100
mov eax,esp
Must remember to move stack pointer back;
storage is limited to stack size;
alloca() not always available in C/C++
Not needed
(fixed allocation!)
mov eax,my_pointer
    resb 100
Wastes space even when not in use;
usually not "threadsafe"