You actually can't manually "free" memory in C, in the sense that the memory is released from the process back to the OS ... when you call malloc()
, the underlying libc-runtime will request from the OS a memory region. On Linux, this may be done though a relatively "heavy" call like mmap()
. Once this memory region is mapped to your program, there is a linked-list setup called the "free store" that manages this allocated memory region. When you call malloc()
, it quickly looks though the free-store for a free block of memory at the size requested. It then adjusts the linked list to reflect that there has been a chunk of memory taken out of the originally allocated memory pool. When you call free()
the memory block is placed back in the free-store as a linked-list node that indicates its an available chunk of memory.
If you request more memory than what is located in the free-store, the libc-runtime will again request more memory from the OS up to the limit of the OS's ability to allocate memory for running processes. When you free memory though, it's not returned back to the OS ... it's typically recycled back into the free-store where it can be used again by another call to malloc()
. Thus, if you make a lot of calls to malloc()
and free()
with varying memory size requests, it could, in theory, cause a condition called "memory fragmentation", where there is enough space in the free-store to allocate your requested memory block, but not enough contiguous space for the size of the block you've requested. Thus the call to malloc()
fails, and you're effectively "out-of-memory" even though there may be plenty of memory available as a total amount of bytes in the free-store.