Allocator
Build a simple malloc
In Linux, a program asks sbrk or brk for space, which increase the heap size and return to a pointer to the start of the new region on the heap. Also, when a program calls malloc(0), it just return NULL. Thus, we can build a simple malloc, to realize how heap works.
1 |
|
It is the easiest malloc function in Linux we build. But it can tell us how heap works. If we need to call a memory block dynamically, we call malloc to allocate some memory from the heap. So, there is a question, how does free work or how do we free it.
Mate-information
We can just return the allocated memory to the system, but it may be going into trouble if we need to call malloc to reserve space each time. Thus, we need to reserve the freed memory for reuse. A common method is to store meta-information about a memory region in some space that we can know which block we can reuse or which is allocated. We need a lightly more space to store some of meta-information like size, isFreed and so on. Also, need a linked list to reserve it. Here is the structure of meta-information containing a pointer to the payload.
1 |
|
But, there is a more significant thing we haven’t thought before. What strategy we use to choose a probe memory block for reuse. The common ways are to return the first memory free block which is larger than or equal to what we want and to return the a memory block with the most suitable size. Each of them has advantages and shortcomings. But we can choose one of them, which is easy to implement, the former one.
Here is the code:
1 |
|
If we can’t find a free block(Maybe it’s the first time to malloc memory space), we have to request space from the system.
1 |
|
With the preparation, we can implement our malloc
and free
without any extra functions.
1 |
|
Realloc and calloc
If we want to add some useful functions to malloc
, we just wrap it and add some functions like initializing memory block or resize a specified memory block. Thus, we build realloc
to resize memory block and calloc
to allocate a memory block with initialization.
Realloc
the prototype of realloc is:
1 |
|
If the size is larger than the size of ptr, we malloc a new memory block with enough space, or just return itself if the size is less then the original.
1 |
|
Calloc
We just initialize all the new memory with 0. It is easy to do but very important for programs.
1 |
|
Merge and Split
The original malloc
and free
will ignore some “extra” space if the size is less than that of the memory block. It wastes a lot of space especially when we use a greedy or extravagant way to distribute memory blocks. Thus, we need a split
function to short some space for other uses and a merge
function to combine two continuous memory block to a larger one.
Merge
Because the continuous memory we request from the heap are stored in the linked list sequentially, we can merge two adjacent element in the list if they are free. Here are codes:
1 |
|
Split
We split a whole memory block into two continuous memory block in the situation where the whole block is quite larger than we need. Thus, we short the size of previous one and construct a new meta structure for the remains. Also, inert it into the list sequentially.
1 |
|
Then, the last step is to modify our malloc
and free
functions to go them into effect.
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!