5月8日

存储管理动态分区分配及回收算法

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 32767

typedef struct Node
{
    int id;            // 分区编号
    int adr;           // 分区首地址
    int size;          // 分区大小
    struct Node *next; // 指向下一个分区
} Node;

// 全局指针定义
Node *head1, *head2; // 空闲队列头指针(First-Fit / Best-Fit)
Node *back1, *back2; // 释放区临时指针
Node *assign;        // 分配区指针
int request;         // 用户申请的内存大小

// 检查释放块合法性
int check(int add, int siz, char c)
{
    Node *p, *head;
    int check = 1;

    if (add < 0 || siz < 0)
    {
        check = 0; // 地址和大小不能为负
    }

    head = (c == 'f' || c == 'F') ? head1 : head2;
    p = head->next;

    while (p != NULL && check)
    {
        // 检查地址是否与空闲区重叠
        if ((add < p->adr && add + siz > p->adr) ||
            (add >= p->adr && add < p->adr + p->size))
        {
            check = 0;
        }
        p = p->next;
    }

    if (!check)
    {
        printf("\t输入释放区地址或大小有错误!!!\n");
    }
    return check;
}

// 初始化空闲队列
void init()
{
    Node *p = (Node *)malloc(sizeof(Node));
    p->size = MAX_SIZE;
    p->adr = 0;
    p->next = NULL;
    p->id = 0;

    head1 = (Node *)malloc(sizeof(Node));
    head2 = (Node *)malloc(sizeof(Node));
    head1->next = p;
    head2->next = p;
}

// First-Fit 分配算法
Node *assignment1(int num, int req)
{
    Node *before = head1;
    Node *after = head1->next;
    Node *ass = (Node *)malloc(sizeof(Node));
    ass->id = num;
    ass->size = req;

    while (after != NULL && after->size < req)
    {
        before = before->next;
        after = after->next;
    }

    if (after == NULL)
    {
        ass->adr = -1; // 分配失败
    }
    else
    {
        if (after->size == req)
        {
            // 精确匹配
            before->next = after->next;
            ass->adr = after->adr;
            free(after);
        }
        else
        {
            // 分割空闲区
            after->size -= req;
            ass->adr = after->adr;
            after->adr += req;
        }
    }
    return ass;
}

// First-Fit 回收算法
void acceptment1(int address, int siz, int rd)
{
    Node *before = head1;
    Node *after = head1->next;
    back1 = (Node *)malloc(sizeof(Node));
    back1->adr = address;
    back1->size = siz;
    back1->id = rd;
    back1->next = NULL;
    int inserted = 0;

    while (!inserted && after != NULL)
    {
        if ((back1->adr <= after->adr) && (back1->adr >= before->adr))
        {
            before->next = back1;
            back1->next = after;
            inserted = 1;
        }
        else
        {
            before = before->next;
            after = after->next;
        }
    }

    if (inserted)
    {
        // 合并相邻空闲区
        if (back1->adr == before->adr + before->size)
        {
            before->size += back1->size;
            before->next = back1->next;
            free(back1);
        }
        else if (after != NULL && back1->adr + back1->size == after->adr)
        {
            back1->size += after->size;
            back1->next = after->next;
            free(after);
        }
        printf("\t首次适应算法回收成功!\n");
    }
    else
    {
        printf("\t首次适应算法回收失败!\n");
    }
}

// Best-Fit 分配算法
Node *assignment2(int num, int req)
{
    Node *before = head2;
    Node *after = head2->next;
    Node *ass = (Node *)malloc(sizeof(Node));
    ass->id = num;
    ass->size = req;

    while (after != NULL && after->size < req)
    {
        before = before->next;
        after = after->next;
    }

    if (after == NULL)
    {
        ass->adr = -1; // 分配失败
    }
    else
    {
        if (after->size == req)
        {
            // 精确匹配
            before->next = after->next;
            ass->adr = after->adr;
            free(after);
        }
        else
        {
            // 分割并重新插入剩余块
            Node *remain = after;
            before->next = after->next;
            ass->adr = remain->adr;
            remain->size -= req;
            remain->adr += req;

            // 将剩余块按大小重新插入队列
            before = head2;
            after = head2->next;
            while (after != NULL && after->size < remain->size)
            {
                before = before->next;
                after = after->next;
            }
            before->next = remain;
            remain->next = after;
        }
    }
    return ass;
}

// Best-Fit 回收算法
void acceptment2(int address, int siz, int rd)
{
    Node *before = head2;
    Node *after = head2->next;
    back2 = (Node *)malloc(sizeof(Node));
    back2->adr = address;
    back2->size = siz;
    back2->id = rd;
    back2->next = NULL;
    int inserted = 0;

    if (head2->next == NULL)
    {
        head2->next = back2;
    }
    else
    {
        // 尝试与前驱合并
        while (after != NULL)
        {
            if (back2->adr == after->adr + after->size)
            {
                after->size += back2->size;
                free(back2);
                back2 = after;
                break;
            }
            after = after->next;
        }

        // 尝试与后继合并
        before = head2;
        after = head2->next;
        while (after != NULL)
        {
            if (after->adr == back2->adr + back2->size)
            {
                back2->size += after->size;
                before->next = after->next;
                free(after);
                break;
            }
            before = before->next;
            after = after->next;
        }

        // 插入到合适位置(按大小升序)
        before = head2;
        after = head2->next;
        while (!inserted)
        {
            if (after == NULL || (after->size > back2->size && before->size < back2->size))
            {
                before->next = back2;
                back2->next = after;
                inserted = 1;
            }
            else
            {
                before = before->next;
                after = after->next;
            }
        }
    }

    printf("\t最佳适应算法回收%s!\n", inserted ? "成功" : "失败");
}

// 打印空闲队列
void print(char choice)
{
    Node *p = (choice == 'f' || choice == 'F') ? head1->next : head2->next;
    if (p != NULL)
    {
        printf("\n空闲区队列情况:\n");
        printf("\t编号\t首址\t终址\t大小\n");
        while (p != NULL)
        {
            printf("\t%d\t%d\t%d\t%d\n", p->id, p->adr, p->adr + p->size - 1, p->size);
            p = p->next;
        }
    }
}

// 主菜单
void menu()
{
    char choice;
    int ch, num = 1, r, add, rd;

    while (1)
    {
        system("cls");
        printf("选择算法:\n");
        printf("F - First-Fit\nB - Best-Fit\nE - 退出\n");
        printf("请输入选择: ");
        scanf(" %c", &choice);

        if (choice == 'e' || choice == 'E')
        {
            exit(0);
        }

        while (1)
        {
            system("cls");
            printf("%s算法模拟:\n", (choice == 'f' || choice == 'F') ? "首次适应" : "最佳适应");
            printf("1. 分配内存\n2. 回收内存\n3. 查看内存\n4. 返回\n");
            printf("请输入操作: ");
            scanf("%d", &ch);

            switch (ch)
            {
            case 1:
                printf("输入申请大小: ");
                scanf("%d", &r);
                assign = (choice == 'f' || choice == 'F') ? assignment1(num++, r) : assignment2(num++, r);
                printf(assign->adr == -1 ? "分配失败!\n" : "分配成功!首址: %d\n", assign->adr);
                break;
            case 2:
                printf("输入释放首址: ");
                scanf("%d", &add);
                printf("输入释放大小: ");
                scanf("%d", &r);
                printf("输入释放编号: ");
                scanf("%d", &rd);
                if (check(add, r, choice))
                {
                    (choice == 'f' || choice == 'F') ? acceptment1(add, r, rd) : acceptment2(add, r, rd);
                }
                break;
            case 3:
                print(choice);
                break;
            case 4:
                return;
            default:
                printf("无效输入!\n");
            }
            system("pause");
        }
    }
}

int main()
{
    init();
    menu();
    return 0;
}

 

posted @ 2025-05-08 15:47  KuanDong24  阅读(9)  评论(0)    收藏  举报