You are on page 1of 3

Memory allocation scheme using the algorithms first-fit, next-fit, and best-fit

/* Implement a memory allocation scheme by using the algorithms first-fit, next-fit, and best-fit.*/
#include <stdio.h>
#define N 100
typedef struct node node;
typedef enum {FALSE, TRUE} bool;
struct node {
char *ptr; // start addr.
int size; // size of the free block.
node *next; // next free block.
};
char mem[N]; // total memory pool.
node freelist; /* the freelist should be sorted on start addr.
* this will ease coalescing adjacent blocks */
void init() {
/* init freelist to contain the whole mem.*/
node *ptr = (node *)malloc( sizeof(node) );
ptr->ptr = mem;
ptr->size = N;
ptr->next = NULL;
freelist.next = ptr;
}
void removenode( node *ptr, node *prev ) {
/* remove a node ptr from the list whose previous node is prev.*/
prev->next = ptr->next;
free(ptr);
}
char *firstfit( int size ) {
/* returns ptr to free pool of size size from freelist.*/
node *ptr, *prev;
char *memptr;
for( prev=&freelist, ptr=prev->next; ptr; prev=ptr, ptr=ptr->next )
if( ptr->size > size ) {
memptr = ptr->ptr;
ptr->size -= size;
ptr->ptr += size;
return memptr;
}
else if( ptr->size == size ) {
memptr = ptr->ptr;
removenode( ptr, prev );
return memptr;
}
return NULL;
}
char *nextfit( int size ) {
/* returns ptr to free pool of size size from freelist.
* the free pool is second allocatable block instead of first.
* if no second block then first is returned. */
bool isSecond = FALSE;
node *prev, *ptr;
node *firstprev, *firstptr;
for( prev=&freelist, ptr=prev->next; ptr; prev=ptr, ptr=ptr->next )
if( ptr->size >= size && isSecond == FALSE ) {
isSecond = TRUE;
firstprev = prev;
firstptr = ptr;
}
else if( ptr->size > size && isSecond == TRUE ) {
char *memptr = ptr->ptr;
ptr->size -= size;
ptr->ptr += size;
return memptr;
}
else if( ptr->size == size && isSecond == TRUE ) {
char *memptr = ptr->ptr;
Memory allocation scheme using the algorithms first-fit, next-fit, and best-fit
removenode( ptr, prev );
return memptr;
}
// ptr is NULL.
ptr = firstptr;
prev = firstprev;
if( ptr->size > size && isSecond == TRUE ) {
char *memptr = ptr->ptr;
ptr->size -= size;
ptr->ptr += size;
return memptr;
}
else if( ptr->size == size && isSecond == TRUE ) {
char *memptr = ptr->ptr;
removenode( ptr, prev );
return memptr;
}
else // isSecond == FALSE
return NULL;
}
char *bestfit( int size ) {
/* returns ptr to free pool of size size from freelist.
the allocated block's original size - size is min in the freelist. */
node *ptr, *prev;
char *memptr;
int minwaste = N+1;
node *minptr = NULL, *minprev;
for( prev=&freelist, ptr=prev->next; ptr; prev=ptr, ptr=ptr->next )
if( ptr->size >= size && ptr->size-size < minwaste ) {
minwaste = ptr->size-size;
minptr = ptr;
minprev = prev;
}
if( minptr == NULL ) // could NOT get any allocatable mem.
return NULL;
ptr = minptr;
prev = minprev;
if( ptr->size > size ) {
memptr = ptr->ptr;
ptr->size -= size;
ptr->ptr += size;
return memptr;
}
else if( ptr->size == size ) {
memptr = ptr->ptr;
removenode( ptr, prev );
return memptr;
}
return NULL;
}
void addtofreelist( char *memptr, int size ) {
/* add memptr of size to freelist.
* remember that block ptrs are sorted on mem addr. */
node *prev, *ptr, *newptr;
for( prev=&freelist, ptr=prev->next; ptr && ptr->ptr<memptr; prev=ptr, ptr=ptr->next )
;
// memptr is to be added between prev and ptr.
newptr = (node *)malloc( sizeof(node) );
newptr->ptr = memptr;
newptr->size = size;
newptr->next = ptr;
prev->next = newptr;
}
void coalesce() {
/* combine adj blocks of list if necessary. */
node *prev, *ptr;
Memory allocation scheme using the algorithms first-fit, next-fit, and best-fit
for( prev=&freelist, ptr=prev->next; ptr; prev=ptr, ptr=ptr->next )
// check for prev mem addr and size against ptr->ptr.
if( prev != &freelist && prev->ptr+prev->size == ptr->ptr ) {/* prev->size += ptr-
>size; */
prev->next = ptr->next;
free(ptr);
ptr = prev;
}
}
char *memalloc( int size ) {
/* return ptr to pool of mem of the size.
* return NULL if NOT available.
* ptr-sizeof(int) contains size of the pool allocated, like malloc. */
char *ptr = bestfit( size+sizeof(int) ); // change this to firstfit() or nextfit().
printf( "allocating %d using bestfit...\n", size );
if( ptr == NULL )
return NULL;
*(int *)ptr = size;
return ptr+sizeof(int);
}
void memfree( char *ptr ) {
/* adds ptr to freelist and combine adj blocks if necessary.
* size of the mem being freed is at ptr-sizeof(int). */
int size = *(int *)(ptr-sizeof(int));
printf( "freeing %d...\n", size );
addtofreelist( ptr-sizeof(int), size+sizeof(int) );
coalesce(); // combine adjacent blocks.
}
void printfreelist() {
node *ptr;
printf( "\t" );
for( ptr=freelist.next; ptr; ptr=ptr->next )
printf( "{%u %d} ", ptr->ptr, ptr->size );
printf( "\n" );
}
int main() { return 0;
char *p1, *p2, *p3, *p4, *p5; }
init(); [vishnu@Algorithmics ~]$ ./a.out
printfreelist(); {6296320 100}
p1 = memalloc(10); allocating 10 using bestfit...
printfreelist(); {6296334 86}
p2 = memalloc(15); allocating 15 using bestfit...
printfreelist(); {6296353 67}
p3 = memalloc(23); allocating 23 using bestfit...
printfreelist(); {6296380 40}
p4 = memalloc(3); allocating 3 using bestfit...
printfreelist(); {6296387 33}
p5 = memalloc(8); allocating 8 using bestfit...
printfreelist(); {6296399 21}
memfree(p1); freeing 10...
printfreelist(); {6296320 14} {6296399 21}
memfree(p5); freeing 8...
printfreelist(); {6296320 14} {6296387 12}
memfree(p3); freeing 23...
printfreelist(); {6296320 14} {6296353 27} {6296387 12}
p1 = memalloc(23); allocating 23 using bestfit...
printfreelist(); {6296320 14} {6296387 12}
p1 = memalloc(23); allocating 23 using bestfit...
printfreelist(); {6296320 14} {6296387 12}
memfree(p2); freeing 15...
printfreelist(); {6296320 14} {6296387 12}
p1 = memalloc(3); allocating 3 using bestfit...
printfreelist(); {6296320 14} {6296394 5}
memfree(p4); freeing 3...
printfreelist(); {6296320 14} {6296380 7} {6296394 5}
p2 = memalloc(1); allocating 1 using bestfit...
printfreelist(); {6296320 14} {6296380 7}
memfree(p1); freeing 3...
printfreelist(); {6296320 14} {6296380 7}
memfree(p2); freeing 1...
printfreelist(); {6296320 14} {6296380 7} {6296394 5}