How does free
work in C?
If you’ve worked in C and ever dynamically allocated memory, you’ve probably used malloc
and free
calls. You put in the amount of memory to be allocated in the malloc
function, it allocates the memory and returns back the starting address of the allocated memory that you store in a pointer variable. Something like this
Before we understand how free
works, we need to quickly look into how does malloc
allocates memory. When you call malloc
with size 512
(say), it will find a place in heap which is atleast 512 bytes wide, mark it as allocated and return the address of the allocated memory. The heap is just a block of memory allocated to the process that maps to an address range.
Let’s take the following simple program
If you run this program in gdb
and look at the memory map using info proc map
, you can see that this address belongs to an address range that’s in the heap region.
The first address does not start from the address 0x602000
instead there is some space ( 16 bits ) before it. Similarly, the next allocated address 0x602220
should be 0x602010 + 512
but it’s not, it’s 0x602010 + 512 + 16
. These extra 2 bytes is where allocation information is stored and while calling free, this information is utilized to free correct amount of memory. This block is called the header for the allocated memory chunk.
Let’s look at this metadata stored in the previous 2 bytes.
The byte just before 0x602010
has the value 0x211
which represents the size of the chunk allocated. Let’s ignore the last bit for a second. If you add, 0x602010 + 0x210
, it gives you the address of the next allocated chunk, i.e. 0x602220
.
The last bit represents that block is allocated. When you call free on this chunk (0x602010
), the value in the meta data is changed to 0x210
which means that this block of size 0x210
is free to be allocated again.
This linked list of dynamically allocated memory is called free list. We iterate this list to find out the which chunk is allocated and which chunk is free. There can be various methods to implement free depending upon the allocator. One can write a custom allocator with a different free implementation with better time/space efficiency. Maybe I’ll write an article on that too 😇.