网上看到的一个实验题:
1、先定义一个全局缓冲区
#define MEMPOOL_SIZE (1024*1024)
static char g_mempool[MEMPOOL_SIZE];
2、实现两个函数my_malloc/my_free,它们都从g_mempool中分配内存,并负责回收,合并等
其原理图如下:
根据原理编写简单的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
/* memory control block */
typedef struct chunk {
char signature[10]; /* "OSEX" */
struct chunk *next; /* ptr. to next chunk */
int state; /* 0-free, 1-used */
int size; /* size of this chunk */
}CHUNK;
void mem_init(void);
void *my_malloc(int num_bytes);
void my_free(void *ptr);
static void show_mem_leak(void);
void test_func(void);
void show_heap_info(void);
#define MEMPOOL_SIZE (1024*1024)
static char g_mempool[MEMPOOL_SIZE]; /* define a global buffer as heap, we use this buffer to test my_malloc/my_free */
static CHUNK *g_chunk_head; /* the head chunk of this heap memory */
enum {FREE = 0, USED};
int main(int argc, char const *argv[])
{
mem_init();
test_func();
return 0;
}
void mem_init(void)
{
g_chunk_head = (CHUNK *)g_mempool;
strcpy(g_chunk_head->signature, "OSEX");
g_chunk_head->next = NULL;
/* the whole memppol is free */
g_chunk_head->state = FREE;
g_chunk_head->size = MEMPOOL_SIZE - sizeof(CHUNK);
atexit(show_mem_leak); /* run show_mem_leak() after the end of main() */
}
void *my_malloc(int num_bytes)
{
CHUNK *ptr = g_chunk_head;
CHUNK *free_chunk;
/* find a free and big-enough chunk */
while(ptr)
{
if(ptr->state == FREE && ptr->size >= num_bytes)
break;
ptr = ptr->next;
}
/* create a new free mem control block */
free_chunk = (CHUNK *) ((char *)(ptr + 1) + num_bytes);
strcpy(free_chunk->signature, "OSEX");
free_chunk->next = NULL;
free_chunk->state = FREE;
free_chunk->size = ptr->size - num_bytes - sizeof(CHUNK);
free_chunk->next = ptr->next;
ptr->state = USED;
ptr->size = num_bytes;
ptr->next = free_chunk;
return (void *)(ptr + 1);
}
void my_free(void *ptr)
{
CHUNK *pre_chunk = g_chunk_head;
CHUNK *this_chunk = (CHUNK *)ptr -1;
CHUNK *next_chunk = this_chunk->next;
if(this_chunk->state == USED && strcmp(this_chunk->signature, "OSEX") == 0)
{
this_chunk->state = FREE;
strcpy(this_chunk->signature, "\0");
}
/* merge right chunk*/
if(next_chunk && next_chunk->state == FREE)
{
this_chunk->next = next_chunk->next;
this_chunk->size = this_chunk->size + sizeof(CHUNK) + next_chunk->size;
}
/* merge left chunk */
while(pre_chunk && pre_chunk->next != this_chunk)
{
pre_chunk = pre_chunk->next;
}
if(pre_chunk && pre_chunk->state == FREE)
{
pre_chunk->next = this_chunk->next;
pre_chunk->size = pre_chunk->size + sizeof(CHUNK) + this_chunk->size;
}
}
static void show_mem_leak(void)
{
CHUNK *ptr = g_chunk_head;
int index = 0;
printf("\n------ memory leak -------\n");
while(ptr)
{
if(ptr->state == USED && strcmp(ptr->signature,"OSEX") == 0)
{
printf("chunk[%d]: address:0x%p size:%d\n", index, ptr, ptr->size);
}
index++;
ptr = ptr->next;
}
}
void test_func(void)
{
int *p1 = my_malloc(100*sizeof(int));
char *p2 = my_malloc(35*sizeof(char));
CHUNK *p3 = my_malloc(30*sizeof(CHUNK));
CHUNK *p4 = my_malloc(50*sizeof(CHUNK));
CHUNK *p5 = my_malloc(15*sizeof(CHUNK));
my_free(p1);
//my_free(p2);
my_free(p3);
//my_free(p4);
my_free(p5);
show_heap_info();
}
void show_heap_info(void)
{
CHUNK *ptr = g_chunk_head;
int index = 0;
while(ptr)
{
printf("-------- chunk[%d] ---------\n", index++);
printf("[address]:0x%p\n", ptr);
printf("[size(bytes)]:%d\n", ptr->size);
printf("[state]:%s\n", (ptr->state? "USED" : "FREE"));
ptr = ptr->next;
}
}
关于malloc其他实现方式:
分析的简单易懂。http://lionwq.spaces.eepw.com.cn/articles/article/item/18555