⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memmgr_win.c

📁 模拟内存管理。 申请内存时
💻 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 + -