用c语言使用首次适应算法实现的内存管理模块
使用全局变量空间而非堆空间
memory.h
#ifndef MEMORY_H
#define MEMORY_H
void *mmalloc(int size);
void mfree(void *ptr);
#endif //MEMORY_H
memory.c
#include "memory.h"
//最多只允许ALLOCATECOUNT个块
#define ALLOCATECOUNT 1000
//可分配内存大小
#define SPACESIZE 1L << 20
#define false 0
#define true !false
#define null (void *)0
typedef char bool;
/**
定义内存块的结构
*/
typedef struct {
char *addr;
int size;
} Memory;
typedef struct {
Memory data[ALLOCATECOUNT];
int ptr;
} MemorySpace;
MemorySpace freeSpace; //空闲内存表
MemorySpace allocateSpace; //已分配内存表
bool isInit = false; //初始化标志
char initSpace[SPACESIZE]; //可分配内存
/**
对指定大小内存区域初始化赋值为data
*/
void mmemset(char *ptr, char data, int size) {
for (int i = 0; i < size; i++) {
ptr[i] = data;
}
}
/**
在space中寻找mem,若找到返回其下标,否则返回-1
*/
int lookupMemory(MemorySpace *space, Memory *mem) {
int left = 0, right = space->ptr;
while (left < right) {
int mid = (left + right) / 2;
if (space->data[mid].addr == mem->addr) {
return mid;
} else if (space->data[mid].addr > mem->addr) {
right = mid;
} else {
left = mid;
}
}
return -1;
}
/**
将mem按addr从小到大的顺序插入到MemorySpace中,成功返回true,若已满返回false
*/
bool insertMemory(MemorySpace *space, Memory mem) {
if (space->ptr == ALLOCATECOUNT) {
return false;
}
int ptr;
for (ptr = space->ptr; ptr > 0; ptr--) {
if (mem.addr >= space->data[ptr - 1].addr) {
break;
}
space->data[ptr] = space->data[ptr - 1];
}
space->data[ptr] = mem;
space->ptr++;
return true;
}
/**
从space中移除mem
*/
bool removeMemory(MemorySpace *space, Memory *mem) {
int ptr = lookupMemory(space, mem);
if (ptr == -1) {
return false;
}
if (ptr != space->ptr - 1) {
for (; ptr < space->ptr - 1; ptr++) {
space->data[ptr] = space->data[ptr + 1];
}
}
space->ptr--;
return true;
}
/**
将space中地址上相邻的内存块合并
*/
void simplify(MemorySpace *space) {
for (int i = space->ptr - 2; i >= 0; i--) {
if (space->data[i].addr + space->data[i].size == space->data[i + 1].addr) {
space->data[i].size += space->data[i + 1].size;
removeMemory(space, &space->data[i + 1]);
}
}
}
/**
初始化各表
*/
void init() {
allocateSpace.ptr = 0;
freeSpace.ptr = 1;
freeSpace.data[0].addr = initSpace;
freeSpace.data[0].size = SPACESIZE;
isInit = true;
}
void *mmalloc(int size) {
if (!isInit) {
init();
}
if (allocateSpace.ptr == ALLOCATECOUNT) {
return null;
}
for (int i = 0; i < freeSpace.ptr; i++) {
if (freeSpace.data[i].size >= size) {
char *tempAddr = freeSpace.data[i].addr;
mmemset(tempAddr, 0, size);
Memory mem = {tempAddr, size};
if (freeSpace.data[i].size == size) {
removeMemory(&freeSpace, &mem);
} else {
freeSpace.data[i].size -= size;
freeSpace.data[i].addr += size;
}
insertMemory(&allocateSpace, mem);
return tempAddr;
}
}
return null;
}
void mfree(void *ptr) {
Memory mem = {ptr, 0};
if (!isInit) {
return;
}
int i = lookupMemory(&allocateSpace, &mem);
if (i == -1) {
return;
}
mem = allocateSpace.data[i];
removeMemory(&allocateSpace, &mem);
insertMemory(&freeSpace, mem);
simplify(&freeSpace);
}
main.c
#include <stdio.h>
#include <string.h>
#include "memory.h"
int main() {
int *x = mmalloc(4);
*x = 0x64656667;
char *str = mmalloc(20);
strcpy(str, "hello, world");
printf("%d\n", *x);
puts(str);
mfree(x);
int *y = mmalloc(4);
printf("%d\n", *y);
mfree(str);
mfree(y);
char *s = mmalloc(24);
puts(s);
mfree(s);
return 0;
}