I wrote a simple memory allocator to substitute malloc/free in libc. The code is so simple~
[torstan]$ more malloc.h
#ifndef _MALLOC_MY_H
#define _MALLOC_MY_H
#include<stdio.h>
void* malloc(size_t sz);
void free(void *p);
#endif
[torstan]$ more malloc.c
#include "malloc.h"
#include <sys/mman.h>
struct _Alloc_header{
void* saddr; //start address
size_t len; //actually allocated length
};
typedef struct _Alloc_header Alloc_header;
void* malloc(size_t sz)
{
if (sz<=0) return NULL;
char *p = 0;
size_t len = sz + sizeof(Alloc_header);
if (len < 1024)
len = 1024;
p = (char*)mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
/*printf("debug: %p, len = %d\n", p, (int)len);*/
if(p == MAP_FAILED)
{printf("failed in mmap!\n"); return NULL;}
Alloc_header *phead = (Alloc_header*)p;
phead->saddr = p;
phead->len = len;
return (void*)(p + sizeof(Alloc_header));
}
void free(void* p)
{
if(p == NULL) return;
Alloc_header* phead = (Alloc_header*)((char*)p - sizeof(Alloc_header));
/*printf("debug: p=%p, phead=%p\n", p, phead);*/
fflush(stdout);
/*printf("debug: free %p, len=%d\n", phead->saddr, (int)phead->len);*/
fflush(stdout);
munmap(phead->saddr, phead->len);
}
[torstan]$ more test.c
#include<stdio.h>
#include<stdlib.h>
int main()
{
int sz = 2000;
char*p = (char*)malloc(sizeof(char)*sz);
printf("malloc size %d, return %p\n", sizeof(char)*sz, p);
free(p);
printf("free size %d, at %p\n", sizeof(char)*sz, p);
return 0;
}
[torstan]$ more Makefile
all:
gcc -Wall -fPIC -c malloc.c
gcc -shared -o libmymalloc.so malloc.o
gcc test.c -o test
clean:
rm *.o *.so test
[torstan]$ make clean
rm *.o *.so test
[tli@bclnx64 memoryStudy]$ make
gcc -Wall -fPIC -c malloc.c
gcc -shared -o libmymalloc.so malloc.o
gcc test.c -o test
[tli@bclnx64 memoryStudy]$ LD_PRELOAD=./libmymalloc.so ./test
malloc size 2000, return 0x2a95658010
free size 2000, at 0x2a95658010
It works!
BTW: I used g++ to compile malloc.cc since it contained a placement new. However, I met with a problem that "test" called free in libc instead of free that I worted, which resulted in a segfault error. I spent sever hours on this problem by googling results and taking practice before I remember a saying that is C++ is evil in some cases. After I substitute the placement new with a pointer conversion and compile the code with gcc, I succeed!