I'm trying to simulate the malloc
function in C by using mmap
and having 2 linked lists to act as memory blocks. The program works by reserving a region of memory and then keeps track of the free and allocated memory address with size in the linked lists. I have tested the program with normal cases like
- free memory > needed to be allocate
- free memory < needed to be allocate
- free memory == needed to be allocate
… but couldn't think of special cases. Are there cases where the program fails?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
struct block {
void *addr; /*start address of memory for this block */
int size;
struct block *next;
};
void *mem;
struct block *freelist;
struct block *allocated_list;
void *smalloc(unsigned int nbytes) {
struct block *cur = freelist;
while(cur!=NULL){
if (cur ->size >= nbytes){
struct block *tempBlock;
tempBlock= malloc(sizeof(struct block));
tempBlock->addr = cur ->addr;
tempBlock->size = nbytes;
tempBlock->next = NULL;
cur->addr = cur->addr + nbytes;
cur ->size = cur ->size - nbytes;
if(allocated_list == NULL){
allocated_list = tempBlock;
}
else{
cur = allocated_list;
while(cur->next!=NULL){
cur =cur->next;
}
cur->next=tempBlock;
}
return (tempBlock->addr);
}
cur = cur->next;
}
return NULL;
}
int sfree(void *addr) {
struct block *cur = allocated_list;
struct block *tempBlock;
while(cur!=NULL){
if (cur ->next->addr == addr){
tempBlock=cur->next; //disjoint the matched block from the allocated_list
cur->next = cur->next->next;
tempBlock->next = NULL; // set the matched block pointing to null
cur = freelist;
while(cur->next!=NULL){
cur =cur->next;
}
cur->next=tempBlock;
return(0);
}
cur= cur->next;
}
return -1;
}
void mem_init(int size) {
mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
if(mem == MAP_FAILED) {
perror("mmap");
exit(1);
}
else {
freelist = malloc(sizeof(struct block));
freelist ->size = size;
freelist ->next = NULL;
freelist ->addr = mem;
allocated_list= NULL;
}
/* NOTE: this function is incomplete */
}
void mem_clean(){
struct block *cur = freelist;
struct block *tempBlock;
while(cur!=NULL){
tempBlock = cur->next;
munmap(cur->addr,cur->size);
free(cur);
cur = tempBlock;
}
cur = allocated_list;
while(cur!=NULL){
tempBlock = cur->next;
munmap(cur->addr,cur->size);
free(cur);
cur = tempBlock;
}
}