Memory management in C is defined as “explicit” because both the operations to reserve and liberate memory need to be explicitly included in the code. In other programming languages, such as for example Java, the execution environment is in charge of recovering those memory portions that are no longer used. Derived from the explicit memory management there are several anomalies that may appear when memory fragments cannot be liberated because there is no possibility to access them. This is what is known as a “memory leak”. This memory portion remains reserved but not accessible until the end of the program execution.
When a program starts to execute, its memory is divided into three portions: the stack, the global memory and the “heap”. The heap is used to reserve and liberate memory portions during the program execution. But, how is this memory actually managed?
The operating system maintains an internal table with all
the memory portion in the heap that are occupied and the pointers returned
as a result of a memory request. When a program executes the
malloc
function to request a new fragment, the system search
for a portion of the requested size, if it exists, returns its initial
address and annotates that block as occupied. Analogously, when a program
calls the function free
to liberate a fragment, the system
searches the table for that fragment (which must be annotated as reserved)
and frees the space for future use. The following figure shows this data
structure and the operations.
At the request of a memory block of 2048 bytes, the memory
manager answers with the address of a block that has previously marked as
occupied. The call to free
is analogous, but instead of a size,
it receives a memory address of a previously reserved block, search that
address in the table, and if exists, it is marked as available.
This memory management scheme forces the programs to follow
very precise guidelines to guarantee a correct use of memory and obtain the
best performance in a program. For example, if a program uses a large
quantity of dynamic data (that is, those stored in memory requested to the
manager through malloc
) and does not free these data as soon as
possible, it may run out of memory and be unable to finish its
execution.