📄 memmgr_win.c
字号:
/*
* 内存管理实验程序残缺版 1.2.2
* 把一个数组模拟为内存,然后针对该块内存实现内存的分配和回收算法
* 作者:Sunner Sun
* 最后修改时间:2005-3-25 16:53
*/
#include <stdio.h>
#define MEM_SIZE 80
char memory[MEM_SIZE];
void* GetBlock(unsigned int size);
int FreeBlock(void* pBlock);
int IsFree(int unit);
struct pliner
{
int start; /*内存块起始单元位置*/
int size; /*内存块大小*/
int free; /*内存块空闲时为1,占用时为0*/
struct pliner *link; /*指向下一块内存*/
};
struct pliner hNode;
/* 在数组memory的分配size大小的内存块,把首地址返回。
如果分配失败,返回NULL */
void* GetBlock(unsigned int size)
{
struct pliner *preNode,*newNode; /*结构体指针preNode为当前节点,newNode为新建节点*/
int preBlock; /*preBlock为分配size大小的内存首地址*/
preNode=&(hNode); /*初始化当前结点为线性表头节点*/
/* 通过线性表分配size大小的内存块,把首地址返回*/
do
{
if ((size<preNode->size)&&(preNode->free==1))/*当申请的内存块大小小于当前节点所指的空闲内存块大小*/
{
newNode=(struct pliner *)malloc(sizeof(struct pliner));
newNode->free=1;
newNode->size=preNode->size-size;
newNode->start=preNode->start+size;
newNode->link=preNode->link;
preBlock=preNode->start;
preNode->size=size;
preNode->free=0;
preNode->link=newNode;
return (&memory[preBlock]); /*将内存块分为两块,并将其链接*/
}
else if ((size==preNode->size)&&(preNode->free==1))
{
preBlock=preNode->start;
preNode->free=0;
return (&memory[preBlock]);
}
preNode=preNode->link;
}while (preNode!=NULL);
printf("\nSystem hasn't enough memory for you!");
return NULL;/*返回首地址*/
}
/* 释放首地址为pBlock的内存块。
成功返回非0值,失败返回0 */
int FreeBlock(void* pBlock)
{
struct pliner *preNode,*prvNode; /*preNode指向释放内存块,prvNode指向所释放内存块的前结点*/
preNode=&(hNode); /*初始化为头节点*/
prvNode=&(hNode); /*初始化为头节点*/
do
{
if (&(memory[preNode->start])==pBlock)
{
if ((preNode->link)->free==1)/*当前节点所指下一个节点为空,合并节点*/
{
preNode->size=preNode->size+(preNode->link)->size;
preNode->link=(preNode->link)->link;
}
if (prvNode->free==1)/*当前节点所指前一个节点为空,合并节点*/
{
preNode->size=preNode->size+prvNode->size;
preNode->start=prvNode->start;
}
preNode->free=1;/*置空当前节点*/
return 1;
}
prvNode=preNode; /*存放前一节点指针*/
preNode=preNode->link; /*后推当前节点*/
}while(preNode!=NULL);
return 0;
}
/* 判断数组memory中下标为unit的单元是否被占用。
空闲返回非0,否则返回0 */
int IsFree(int unit)
{
struct pliner *pl;/*指向结构体指针*/
pl=&(hNode);
do
{
if ((unit>=pl->start)&&(unit<(pl->start+pl->size))&&pl->free==1)
return !0;/*如果unit在当前节点所指内存块范围内,且内存块为空,返回1*/
pl=pl->link;
}while (pl!=NULL);
return 0;
}
/************************************************
* 下面为测试代码,不需要修改,也不许使用其定义 *
* 的各种变量、宏、结构等 *
************************************************/
#define MAX_BLOCK_SIZE 10
#define BLOCK_COUNT 80
struct BLOCK
{
void* p;
int size;
};
void PrintMemoryUsage(void);
int New(struct BLOCK *pBlocks);
int Delete(struct BLOCK *pBlocks);
int main(void)
{
struct BLOCK blocks[BLOCK_COUNT] = {0,0};
int ch = 0;
int rtn = 1;
int i;
/*初始化虚拟内存空间*/
hNode.size=80;
hNode.start=0;
hNode.free=1;
hNode.link=NULL;
do
{
switch (ch)
{
case 'n':
rtn = New(blocks);
break;
case 'd':
rtn = Delete(blocks);
break;
case '\n':
continue;
break;
}
if (!rtn)
printf("\nError!!!!\n");
PrintMemoryUsage();
printf("Input \'n\' to new, \'d\' to delete and \'q\' to quit:");
} while ((ch=getchar()) != 'q');
/* 删除所有已申请的block */
for (i=0; i<BLOCK_COUNT; i++)
{
if (blocks[i].p != NULL)
{
FreeBlock(blocks[i].p);
}
}
return 0;
}
/* 打印memory分配情况 */
void PrintMemoryUsage(void)
{
int i;
putchar('\n');
for (i=0; i<MEM_SIZE; i++)
{
if (i%10 == 0)
putchar('|');
else
putchar(' ');
}
putchar('\n');
for (i=0; i<MEM_SIZE; i++)
{
if (IsFree(i))
putchar('-');
else
putchar('*');
}
putchar('\n');
}
/* 新申请block */
int New(struct BLOCK *pBlocks)
{
int size = 0;
while (size < 1 || size > MAX_BLOCK_SIZE)
{
printf("Size?[1-%d]", MAX_BLOCK_SIZE);
scanf("%d", &size);
}/*申请内存大小限制问题*/
while (pBlocks->p != NULL)
pBlocks++;
pBlocks->p = GetBlock(size);
pBlocks->size = size;
return (pBlocks->p != NULL);
}
/* 删除已经申请的block */
int Delete(struct BLOCK *pBlocks)
{
int i;
for (i=0; i<BLOCK_COUNT; i++)
{
if (pBlocks[i].p != NULL)
{
printf("%d:%d\t", i, pBlocks[i].size);
}
}
printf("\nWhich to delete:");
scanf("%d", &i);
if (FreeBlock(pBlocks[i].p))
{
printf("\nHello\n");
pBlocks[i].p = NULL;
return !0;
}
else
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -