I implement a custom memory allocator. All my main code for this inside file memory.c
I create a main function in this file to test function. All works fine. But when I move those testing code to another file (calling main.c
and run it. I meet Segmentation fault.
int main (int argc, char *argv []) {
allocator_init();
char* ptr = (char*) allocate(4096); // csutom function. that on `memory.c`
strcpy(ptr, "this is the test one");// segmentation fault here
printf("print: %s\n", ptr);
deallocate(ptr);
}
Here is the main code :
volatile Memory memory;
/* allocated memory to memory variable by assign /dev/zero to memory */
void allocator_init() {
fd = open("/dev/zero", O_RDWR);
if(fd == -1) {
perror("File open failed");
exit(0);
}
// page size can different on different platform. customize again to optimize
PAGE_SIZE = getPageSize();
// fd = open("ZEROES", O_RDWR);
if(fd == -1) {
perror("File open failed");
exit(0);
}
// Initialize the region list
memory.region = NULL;
int i;
/// Initialize the caches
/// size of each cache is 16 * 2^i => 16, 32, 64, 128, 256, 512, 1024, 2048
for (i=0; i<8; i++) {
memory.cache[i].size = 16<<i;
memory.cache[i].S = NULL;
}
return;
}
void *allocate_region (unsigned int size) {
Region *region, *temp;
temp = memory.region;
void *mapped_addr = mmap(NULL, size + REGION_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if(mapped_addr == MAP_FAILED) {
perror("Mapping failed");
exit(0);
}
/* create region from mapped address */
region = mapped_addr;
region->size = size;
region->addr = mapped_addr + REGION_SIZE;
printf("allocated region: %p\n", region->addr);
/* assign this region to memory */
memory.region = region;
/* just simple append algorithm in linked list. so new region will be appended to head of linked list */
region->next = temp;
return region->addr;
}
/* allocate : if size < 2048 : allocate cache. else allocate region */
void *allocate(unsigned int size) {
size = ALIGN(size);
return allocate_region(size);
}
Here is memory.h
define all struct that i have used:
#ifndef MEMORY_H
#define MEMORY_H
#define MAX_SIZE (1024*1024)
#define REGION_SIZE sizeof(Region)
#define SLAB_SIZE sizeof(Slab)
#define WORD_SIZE 32
#define ALIGNMENT 8
/* rounds up to the nearest multiple of ALIGNMENT */
#define ALIGN(size) (((size) + (ALIGNMENT-1)) & ~0x7)
#define SIZE_T_SIZE (ALIGN(sizeof(size_t)))
#define TRUE 1
#define FALSE 0
#define MAX_SIZE 10000
// Caches are:
// 16, 32, 64, 128, 256, 512, 1024, 2048
#include "bits.h"
int PAGE_SIZE;
// File descriptor for zeroes file
int fd;
void allocator_init();
int deallocate_cache(void* ptr);
void *allocate(unsigned int size);
typedef struct __Region {
void *addr; /// started address can use for caller (can calc by allocated address + Region size)
int size; /// size of this allocated Region (not include size Region)
struct __Region *next;
} Region;
/// size of Slab equals to size of System Page
typedef struct __Slab {
void *addr; /// address of this slab (exclude header)
char *bitmap; /// started address can use for caller (can calc by allocated address + slab size)
int size;
int slots; /// number of slots in maximum has been used
int cache_size; /// size of cache that contains this slab
int bitmap_size; /// size of bitmap. so, can count address bit by bitmap + bitmap_size
int currentSize; /// current allocated elements of this slab. currentSize = 0. deallocated this slab
int bit; /// bit to marked which part of slab has been used
struct __Slab * next;
} Slab;
typedef struct __Cache {
int size;
Slab *S;
} Cache;
typedef struct __Memory {
Region *region;
Cache cache[8];
} Memory;
#endif // MEMORY_H
above code will works fine, allocate
function return an address. I just meet error when move to another file. in my memory.c
, I have some global variable to control allocated address and memory. Does it affect when I move code to new file ? I cannot explain this.
Thanks :)