Objects in C can have one of three storage durations:
Objects with static storage duration have memory allocated for them when the program starts up, and the memory won't be released until the program exits. This is usually done by reserving space within the program image itself; IOW, the binary file of your program has a few sections reserved for constant (.rdata
or .rodata
) and non-constant (.bss
) data. That's what they mean by being reserved at compile time; the compiler sets aside sections within the generated binary file for data storage. These sections aren't usable until the program is loaded into memory and run, though.
Objects with auto storage duration have memory allocated for them at runtime when the program enters their enclosing scope and released when the program exits that scope.
Given the following code:
void foo( void )
{
int x;
for ( x = 0; x < 100; x++ )
{
int y = x * 2;
...
}
}
Logically speaking, the space for x
will be set aside when you enter the function foo
and held until foo
exits, and the space for y
will be set aside when you enter the for
loop and released when the loop exits. In practice (at least on the platforms I'm familiar with), the space for both will be set aside at function entry and released at function exit, but you shouldn't assume that the space for y
will be usable outside of the loop.
Most systems use a stack for managing objects with auto storage duration1.
Objects with dynamic storage duration have their memory set aside by calling the library functions malloc
, calloc
, or realloc
, and that memory is held until it is explicitly released with a call to free
:
void *foo( void )
{
void *mem = malloc( SOME_MEMORY );
...
return mem;
}
void bar( void )
{
void *data = foo();
...
free( data );
}
The variables mem
and bar
both have auto storage duration. mem
only exists within foo
and data only exists within bar
. However, the object they both point to has dynamic storage duration; it is allocated in foo
and held until explcitly released in bar
.
The memory pool for these objects is usually referred to as the "heap".
1. C was originally designed on systems that used a stack for managing runtime data, so it's a natural way to implement the behavior of auto
variables. However, the language definition is written in such a way to accomodate non-stack-based systems, although they'd be a pain in the ass to implement.