Here all the free memory is stored in one free list
Each chunk in the free list has a header with the size of the chunk and a pointer to the next one
During allocation, a chunk of the right size is searched for, split if necessary, and returned to the user with the remainder returned to the free list
When an object is freed, the free list is traversed to find the right place of insertion and its coalesced if possible
If the request cannot be satisfied in the existing free list, the allocator gets memory from the OS
Memory is requested in larger chunks so as to reduce the amount of times it is requested
There are two primary allocation policies
First fit: Use the first chunk in the free list that satisfies the request
Faster
If the search always starts at the beginning, then there will end up being a lot of small objects at the beginning
An alternative is Next fit: like first fit except it starts where the last search ended, solving the above issue
Best fit: Choose the smallest chunk that satisfies the request
Search for the first object that is large enough to satisfy the request and split it. Use on portion of the object to satisfy the allocation request and return the reaminder to the free list
If the remainder is smaller than the size of the header plus the next/prev pointers making the object unusable, then do not split the object and use the entire object to satisfy the allocation
If there is not enough memory in the free lists to satsify the allocation, request more from the OS using sbrk(). Roudn up the request of memory to the OS to the arena size. Request mulotiple times from the OS if the ojbect is larger than the arena.
Check the header of the left neighbor object (the object just befojre the object being freed) to see if it is also free. If that is the case, remove the left neighbro from its free list using the previous/next pointers and coalesce this object with the object being freed
Check the right neighbor object to see if it is also freee. If that is the case remove it from its free list and coalesce it
Place the freed object in the corresponding free list and update the header and header of the next object
The freed object is added to the free list, modifying the pointers
If the object is then modified, the next/prev pointers may be overwritten causing further calls to malloc/free to crash
Premature frees are often hard to debug because the crash can happen far away from the source of the error
They also lead to security vulnerabilities
int * p = (int *)malloc(sizeof(int));* p = 8;* free(p); // free adds object to free list// updating next and prev … *p = 9; // next ptr will be modified. … int q = (int *)malloc(sizeof(int)); // this call or other future malloc/free // calls will crash because the free list is corrupted
To minimize the impact of premature frees (and double frees) set p=NULL after its freed
Causes overwriting the header of the object that follows, corrupting the free list
Subsequent calls may crash
Sometimes the smashing happens in the unused portion of the object, causing no immediate errors
char * s = malloc(8);strcpy(s, "hello world cs252 students");// allocating less memory for the string than the memory being used// which will overwrite the pointers of the object AFTER s