/*
Coder:LUCY_Zhang LSQ(647) XQF~
*/
#include "mem.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h> //mmap()
#include <assert.h>
#include <unistd.h> //getpagesize()
int m_error;
//空闲区域头部结构
typedef struct _header_t
{
/* data */
int size;
struct _header_t* next;
}header_t;
//已分配区域头部结构
typedef struct _node_t
{
/* data */
int size;
int magic;
}node_t;
#define LEN_H sizeof(header_t)
#define LEN_N sizeof(node_t)
//全局变量
header_t* head = NULL;
header_t* last = NULL;
//只能初始化一次
int INIA = 0;
//自定义函数
//******************************************************************************************
//对齐
int align_size(int size_o){
int size_n;
size_n = ((size_o-1)/8+1)*8;
size_n = size_n + LEN_N;
return size_n;
}
/* First fit */
header_t* find_first(int s) {
header_t* p = head;
s = s - LEN_H;
while(p && (p->size < s)) {
last = p;
p = p->next;
}
return p;
}
/*best fit*/
header_t* find_best(int s){
header_t* p = head;
header_t* cur = NULL;
header_t* last_tmp = NULL;
int min = 888888;
s = s - LEN_H;
while(p) {
if(p->size >= s){
if(p->size < min){
last = last_tmp;
min = p->size;
cur = p;
cur->size =p->size;
}
}
last_tmp = p; //执行顺序不能错!!!
p = p->next;
}
return cur;
}
/*worst fit*/
header_t* find_worst(int s){
header_t* p = head;
header_t* cur = NULL;
header_t* last_tmp = NULL;
int max = 0;
s = s - LEN_H;
while(p) {
if(p->size >= s){
if(p->size > max){
last = last_tmp;
max = p->size;
cur = p;
cur->size =p->size;
}
}
last_tmp = p; //执行顺序不能错!!!
p = p->next;
}
return cur;
}
//分割
node_t* split_block(header_t* b, int s) {
header_t* c = b;
if(b->size >= s){ //enough for head
b=(void*)b+s; //***************************************
b->size = c->size - s;
b->next = c->next;
if(c==head || last==NULL)
head = b;
else
last->next = b;
}
else{
if(c==head || last == NULL)
head = b->next;
else
last->next = b->next;
}
/*返回指针*/
node_t* re = (void*)c; //********************************************
re->size = s-LEN_N;
re->magic = 1234567;
node_t* retur = (void*)c+LEN_N;
return retur;
}
//******************************************************************************************
int mem_init(int size_of_region){
//size小于等于0 或者 调用不止一次时 返回失败!
if(size_of_region <= 0 || INIA){
m_error = E_BAD_ARGS;
return -1;
}
else{
INIA = 1;
int page = getpagesize();
size_of_region = ((size_of_region-1)/page + 1)*page ;
head = mmap(NULL, size_of_region, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
//调用失败
if(head == MAP_FAILED){
m_error = E_NO_SPACE;
return -1;
}
else{
head->size = size_of_region - LEN_H;
head->next = NULL;
return 0;
}
}
}
void * mem_alloc(int size, int style){
//对齐地址
header_t* tmp;
last = head;
int news = align_size(size);
// 三种分配方式
if(style == M_BESTFIT){
tmp = find_best(news);
if(tmp) {
node_t* result = split_block(tmp, news);
//printf("***%d*****%d\n",result->size,result->magic);
//printf("result : %d\n",result);
return result;
}
else{
m_error = E_NO_SPACE;
return NULL;
}
}
else if(style == M_WORSTFIT){
tmp = find_worst(news);
if(tmp) {
node_t* result = split_block(tmp, news);
//printf("***%d*****%d\n",result->size,result->magic);
//printf("result : %p\n",result);
return result;
}
else{
m_error = E_NO_SPACE;
return NULL;
}
}
else if(style == M_FIRSTFIT){
tmp = find_first(news);
if(tmp) {
node_t* result = split_block(tmp, news);
//printf("***%d*****%d\n",(int)result,result->magic);
//printf("result : %p\n",result);
return result;
}
else{
//printf("not enough memory\n");
m_error = E_NO_SPACE;
return NULL;
}
}
else
{
printf("Please choose a kind of style.\n");
return NULL;
}
}
int mem_free(void * ptr){
int h=0,t=0;
//对于空指针什么也不做;
if(ptr == NULL)
return 0;
//printf("###############%d\n",ptr);
//找到隐藏的头部指针
ptr -= LEN_N; //先得到隐藏的指针才能判断
if(((node_t*)ptr)->magic != 1234567){
m_error = E_BAD_POINTER;
return -1;
}
header_t* hptr = ptr;
hptr->size = ((node_t*)ptr)->size+LEN_N-LEN_H;
hptr->next = NULL;
//找到返回的块的前后空闲块
header_t* aftr = NULL;
header_t* prev = NULL;
header_t* m = head;
//遍历
//printf("_____________%d,%d\n",m,hptr);
while(m && m < hptr){
//printf("~~~~~~~~~~~~~~%d__%d_____\n",m,hptr);
prev = m;
m = m->next;
}
aftr = m;
//printf("~~~~~after:%d__hptr:%d_____\n",aftr,hptr);
int t1 = hptr->size + LEN_H;
int t2 = (void*)aftr - (void*)hptr;
if(prev) {
int h1 = prev->size + LEN_H;
int h2 = (void*)hptr - (void*)prev;
//printf(" h1:%d h2:%d\n",h1,h2);
if(h1==h2)
h=1;
}
if(aftr && (t2 == t1)) t=1;
//printf(" t1:%d t2:%d h:%d t:%d\n",t1,t2,h,t);
if(h && t){ //有头有尾
prev->size = prev->size + LEN_H + hptr->size + LEN_H + aftr->size;
prev->next = aftr->next;
}
else
if(h && !t){ //有头无尾
prev->size = prev->size + LEN_H + hptr->size;
}
else
if(!h && t){ //无头有尾
if(prev){
prev->next = hptr;
hptr->next = aftr->next;
hptr->size = hptr->size + LEN_H + aftr->size;
}
else{
hptr->next = aftr->next;
head = hptr;
hptr->size = hptr->size + LEN_H + aftr->size;
}
}
else{ //无头无尾
if(prev){
prev->next = hptr;
hptr->next = aftr;
}
else{
hptr->next = aftr;
head = hptr;
}
}
return 0;
}
//打印未分配区域
void mem_dump(){
header_t* i = head;
//printf("head : %d\n",head);
while(i){
if(i->next!=NULL)
printf("now:%p__size:%d__next:%p\n",i, (int)(i->size+LEN_H-LEN_N), (i->next));
else
printf("now:%p__size:%d__next:%p\n",i, (int)(i->size+LEN_H-LEN_N), i->next);
i = i->next;
}
printf("******************************************************\n");
}
mem.rar_Free!_malloc_malloc和free_mem_free_mem_malloc
版权申诉
107 浏览量
2022-09-20
22:19:24
上传
评论
收藏 2KB RAR 举报
我虽横行却不霸道
- 粉丝: 72
- 资源: 1万+