Silviu.
Silviu.

Reputation: 585

Dynamic memory allocator (heap)

My goal is to create my own "malloc" and "free" functions. I'm only doing this for practice so I'm not interested in speed/performance. Instead I would go for a an easy approach so I can understand easier.

Where can I get started with this? Can you give me some pointers as to how to do it or tell me what I need to use to create these functions?

Upvotes: 0

Views: 368

Answers (3)

Havenard
Havenard

Reputation: 27854

jemalloc is a free, open-source, thread-safe replacement for the libc malloc(). Its code is fairly simple, and studying it you will find everything you need to know about creating your own replacement for malloc and other libc functions including:

  • How to make the compiler use your malloc instead of the native libc's for everything, including the malloc() calls in the inner guts of the libc functions;
  • How to make it thread-safe;
  • How to make it compilable and functional in every platform.

Notice NetBSD and FreeBSD already use jemalloc as default memory allocator.

Upvotes: 1

Hiren Pandya
Hiren Pandya

Reputation: 995

Below is the solution. This code helped me, I got it from IBM Developers.

/* Include the sbrk function */ 
#include <unistd.h> 

int has_initialized = 0; 
void *managed_memory_start; 
void *last_valid_address; 

void malloc_init() 
 { 
   /* grab the last valid address from the OS */ 
   last_valid_address = sbrk(0); 

 /* we don't have any memory to manage yet, so 
  *just set the beginning to be last_valid_address 
  */ 
  managed_memory_start = last_valid_address; 

  /* Okay, we're initialized and ready to go */ 
  has_initialized = 1; 
} 

 struct mem_control_block { 
  int is_available; 
  int size; 
 };  

 void free(void *firstbyte) { 
   struct mem_control_block *mcb; 

  /* Backup from the given pointer to find the 
  * mem_control_block 
   */ 
    mcb = firstbyte - sizeof(struct mem_control_block); 
   /* Mark the block as being available */ 
    mcb->is_available = 1; 
   /* That's It! We're done. */ 
   return; 
  } 

 void *malloc(long numbytes) { 
     /* Holds where we are looking in memory */ 
     void *current_location; 

    /* This is the same as current_location, but cast to a 
    * memory_control_block 
    */ 
    struct mem_control_block *current_location_mcb; 

    /* This is the memory location we will return. It will 
    * be set to 0 until we find something suitable 
    */ 
      void *memory_location; 

/* Initialize if we haven't already done so */ 
if(! has_initialized) { 
malloc_init(); 
} 

/* The memory we search for has to include the memory 
* control block, but the user of malloc doesn't need 
* to know this, so we'll just add it in for them. 
*/ 
numbytes = numbytes + sizeof(struct mem_control_block); 

/* Set memory_location to 0 until we find a suitable 
*
 location 
*/ 
memory_location = 0; 

/* Begin searching at the start of managed memory */ 
current_location = managed_memory_start; 

/* Keep going until we have searched all allocated space */ 
while(current_location != last_valid_address) 
{ 
/* current_location and current_location_mcb point 
* to the same address. However, current_location_mcb 
* is of the correct type so we can use it as a struct. 
* current_location is a void pointer so we can use it 
* to calculate addresses. 
*/ 
current_location_mcb = 
(struct mem_control_block *)current_location; 

if(current_location_mcb->is_available) 
{

if(current_location_mcb->size >= numbytes) 
{ 
/* Woohoo! We've found an open, 
* appropriately-size location. 
*/ 

/* It is no longer available */ 
current_location_mcb->is_available = 0; 

/* We own it */ 
memory_location = current_location; 

/* Leave the loop */ 
break; 
} 
} 

/* If we made it here, it's because the Current memory 
* block not suitable, move to the next one 
*/ 
current_location = current_location + 
current_location_mcb->size; 
} 

/* If we still don't have a valid location, we'll 
* have to ask the operating system for more memory 
*/ 
if(! memory_location) 
{ 
/* Move the program break numbytes further */ 
sbrk(numbytes); 

/* The new memory will be where the last valid 
* address left off 
*/ 
memory_location = last_valid_address; 

/* We'll move the last valid address forward 
* numbytes 
*/ 
last_valid_address = last_valid_address + numbytes; 

/* We need to initialize the mem_control_block */ 
current_location_mcb = memory_location; 
current_location_mcb->is_available = 0; 
current_location_mcb->size = numbytes; 
} 

/* Now, no matter what (well, except for error conditions), 
* memory_location has the address of the memory, including 
* the mem_control_block 
*/ 

/* Move the pointer past the mem_control_block */ 
memory_location = memory_location + sizeof(struct mem_control_block); 

/* Return the pointer */ 
return memory_location; 
}

Hope it helps...

This may get handy... http://stackoverflow.com/questions/13764711/making-your-own-malloc-function-in-c

Upvotes: 1

AurA
AurA

Reputation: 12363

The answer is more of a redirection to previous questions

For Malloc making your own malloc function in C

For Free C - Design your own free( ) function

And one blog http://www.dreamincode.net/forums/topic/178691-creating-a-custom-malloc-and-free-in-c/

Upvotes: 2

Related Questions