一、内存检查的实现逻辑
1、内存余量检查的步骤
①、选定一块地址范围
②、在地址范围内,依次给地址写入值
③、写入值之后,将写入的值反转
④、把反转后的值读出,检查反转值是否正确,
⑤、把反转后的值再次反转
⑥、检查是否恢复原值,以判断地址空间是否可用
2、为什么选择检查的范围是0x400000~0xbfff ffff
因为0x400000以前的地址,已经被操作系统占用,而且是不能随意更改的系统根基。
我们做内存管理,管理的是空闲可用的地址范围址。
二、内存管理的两种方式
1、数组管理
创建一个大数组
使用数组值1代表内存已经使用
使用数组值0代表内存尚未使用
2、结构体管理
创建一个结构体列表
列表中记录空闲位置的起始地址、字节长度
三、内存管理的实现代码
这里使用的是第二种方式结构体管理法。
struct FREEINFO { /* あき情報 */
unsigned int addr, size;
};
struct MEMMAN { /* メモリ管理 */
int frees, maxfrees, lostsize, losts;
struct FREEINFO free[MEMMAN_FREES];
};
unsigned int memman_alloc(struct MEMMAN *man, unsigned int size)
/* 確保 */
{
unsigned int i, a;
for (i = 0; i < man->frees; i++) {
if (man->free[i].size >= size) {
/* 十分な広さのあきを発見 */
a = man->free[i].addr;
man->free[i].addr += size;
man->free[i].size -= size;
if (man->free[i].size == 0) {
/* free[i]がなくなったので前へつめる */
man->frees--;
for (; i < man->frees; i++) {
man->free[i] = man->free[i + 1]; /* 構造体の代入 */
}
}
return a;
}
}
return 0; /* あきがない */
}
int memman_free(struct MEMMAN *man, unsigned int addr, unsigned int size)
/* 解放 */
{
int i, j;
/* まとめやすさを考えると、free[]がaddr順に並んでいるほうがいい */
/* だからまず、どこに入れるべきかを決める */
for (i = 0; i < man->frees; i++) {
if (man->free[i].addr > addr) {
break;
}
}
/* free[i - 1].addr < addr < free[i].addr */
if (i > 0) {
/* 前がある */
if (man->free[i - 1].addr + man->free[i - 1].size == addr) {
/* 前のあき領域にまとめられる */
man->free[i - 1].size += size;
if (i < man->frees) {
/* 後ろもある */
if (addr + size == man->free[i].addr) {
/* なんと後ろともまとめられる */
man->free[i - 1].size += man->free[i].size;
/* man->free[i]の削除 */
/* free[i]がなくなったので前へつめる */
man->frees--;
for (; i < man->frees; i++) {
man->free[i] = man->free[i + 1]; /* 構造体の代入 */
}
}
}
return 0; /* 成功終了 */
}
}
/* 前とはまとめられなかった */
if (i < man->frees) {
/* 後ろがある */
if (addr + size == man->free[i].addr) {
/* 後ろとはまとめられる */
man->free[i].addr = addr;
man->free[i].size += size;
return 0; /* 成功終了 */
}
}
/* 前にも後ろにもまとめられない */
if (man->frees < MEMMAN_FREES) {
/* free[i]より後ろを、後ろへずらして、すきまを作る */
for (j = man->frees; j > i; j--) {
man->free[j] = man->free[j - 1];
}
man->frees++;
if (man->maxfrees < man->frees) {
man->maxfrees = man->frees; /* 最大値を更新 */
}
man->free[i].addr = addr;
man->free[i].size = size;
return 0; /* 成功終了 */
}
/* 後ろにずらせなかった */
man->losts++;
man->lostsize += size;
return -1; /* 失敗終了 */
}