#include <stdio.h>
typedef unsigned int UINT32;
#define MCB_LEN 10 //内存记录块的总长度
#ifdef _DEBUG
#define debug_printf printf //调试信息输出
#else
#define debug_printf //以Release方式编译时不产生实际代码
#endif
typedef struct{
void *addr; //空闲空间或已使用空间的首地址
UINT32 size; //空闲空间或已使用空间的大小,以四字节为一个单位
UINT32 status; //状态标识 已使用(used=0) 未使用(unused=1)
}mem_ctrl_block;
enum{
used = 0 ,
unused = 1
};
static UINT32 _mem[0x1000]; //初始的可用内存空间
static mem_ctrl_block mcb[MCB_LEN+2]; //多分配两个mem_ctrl_block的空间,便于移动数组记录
static UINT32 mcb_count; //mcb记录总数,范围 1 - MCB_LEN
void mcb_info_out()
{
register UINT32 i;
printf("当前内存使用记录如下:/n");
for(i=0 ; i<mcb_count ; i++){
printf("起始地址:0x%p 空间大小:%8d字节 ",mcb[i].addr,(mcb[i].size<<2));
if(mcb[i].status){
printf("当前状态:空闲/n");
}
else{
printf("当前状态:占用/n");
}
}
return;
}
void mcb_init()
{
mcb[0].addr = _mem;
mcb[0].size = sizeof(_mem)>>2;
mcb[0].status = unused;
mcb_count = 1;
#ifdef _DEBUG
mcb_info_out();
#endif
}
void* myMalloc(UINT32 size)
{
register UINT32 sz;
register UINT32 i,j;
if (mcb_count == MCB_LEN){
debug_printf("/n内存记录空间已满,分配失败!/n");
return NULL;
}
if (size == 0){
debug_printf("/n申请内存空间大小为0!/n");
return NULL;
}
sz = ((size&3) == 0) ? (size>>2) : ((size>>2) + 1);//归一化为以四字节为单位的值
for (i=0 ; i<mcb_count ; i++)
{
//找到一个空间大小足够的内存空闲空间
if (mcb[i].status && (mcb[i].size >= sz))
{
if (mcb[i].size == sz){
mcb[i].status = used;
}
else{
for (j=mcb_count ; j>i ; j--){
mcb[j].addr = mcb[j-1].addr;
mcb[j].size = mcb[j-1].size;
mcb[j].status = mcb[j-1].status;
}
mcb[i+1].addr = (UINT32*)mcb[i].addr + sz;
mcb[i+1].size = mcb[i].size - sz;
mcb[i+1].status = unused;
mcb[i].size = sz;
mcb[i].status = used;
mcb_count++;
}
debug_printf("/n申请内存空间大小为%d字节,分配成功!/n",size);
#ifdef _DEBUG
mcb_info_out();
#endif
return mcb[i].addr;
}
}
debug_printf("/n申请内存空间大小为%d字节,空间不足,分配失败!/n",size);
return NULL;
}
void myFree(void *memblock)
{
register UINT32 i,j;
for (i=0 ; i<mcb_count ; i++)
{
if ( mcb[i].status==used && (mcb[i].addr == memblock))
{
//前后相邻的内存空间均空闲
if (mcb[i-1].status && mcb[i+1].status)
{
mcb[i-1].size += (mcb[i].size + mcb[i+1].size);
for (j=i; j<mcb_count; j++){
mcb[j].addr = mcb[j+2].addr;
mcb[j].size = mcb[j+2].size;
mcb[j].status = mcb[j+2].status;
}
mcb_count -= 2;
}
else
//前向相邻的内存空间空闲
if (mcb[i-1].status && (!mcb[i+1].status))
{
mcb[i-1].size += mcb[i].size;
for (j=i ; j<mcb_count; j++){
mcb[j].addr = mcb[j+1].addr;
mcb[j].size = mcb[j+1].size;
mcb[j].status = mcb[j+1].status;
}
mcb_count--;
}
else
//后向相邻的内存空间空闲
if ((!mcb[i-1].status) && mcb[i+1].status)
{
mcb[i].size += mcb[i+1].size;
mcb[i].status = unused;
for (j=i+1 ; j<mcb_count; j++){
mcb[j].addr = mcb[j+1].addr;
mcb[j].size = mcb[j+1].size;
mcb[j].status = mcb[j+1].status;
}
mcb_count--;
}
else{
mcb[i].status = unused;//相邻的内存空间均处于使用状态
}
debug_printf("/n请求释放空间的起始地址:0x%p,释放成功!/n",memblock);
#ifdef _DEBUG
mcb_info_out();
#endif
return;
}
}
debug_printf("/n请求释放空间的起始地址:0x%p,非法指针,释放失败!/n",memblock);
return;
}
int main(int argc, char *argv[])
{
UINT32 *p[10],i;
mcb_init();
/*Test1 包含以下情况
1.申请的空间大小为0
2.申请的空间大小超过可分配大小
3.内存记录数组满
4.申请内存空间的大小不等于首次匹配的空闲空间大小
*/
p[0]=(UINT32*)myMalloc(0);
p[0]=(UINT32*)myMalloc(0xFFFFFF);
for (i=0 ; i<10 ;i++){
p[i] = (UINT32*)myMalloc(i+1);
}
/*Test2 包含以下情况
1.请求释放空间的前后相邻内存空间均处于使用状态
2.请求释放空间的前向相邻内存空间处于空闲状态
3.请求释放空间的后向相邻内存空间处于空闲状态
4.请求释放空间的前后相邻内存空间均处于空闲状态
5.请求释放空间的地址非法
6.申请内存空间的大小恰等于首次匹配的空闲空间大小
7.申请内存空间的大小不等于首次匹配的空闲空间大小
*/
myFree(p[1]); //情况1
myFree(p[5]); //情况1
myFree(p[2]); //情况2
myFree(p[6]); //情况2
myFree(p[0]); //情况3
myFree(p[4]); //情况3
myFree(p[3]); //情况4
myFree(p[9]); //情况5
myFree(p[0]); //情况5
p[9]=(UINT32*)myMalloc(40); //情况6
myFree(p[7]); //情况1
p[7]=(UINT32*)myMalloc(4); //情况7
myFree(p[8]); //情况4
myFree(p[7]); //情况3
myFree(p[9]); //情况3
return 0;
}
修改注明:本程序 所有同学可以借鉴。但切莫完全CTRL+V。否则后果自负(已经提交过给老师了。)。。。
顺便给你们指引个方向,可以改写成C++的。 免得出事情。
C++模拟内存管理
最新推荐文章于 2022-11-20 13:16:12 发布