📜  内存管理中的最差拟合算法程序(1)

📅  最后修改于: 2023-12-03 15:36:48.528000             🧑  作者: Mango

最差拟合算法程序介绍

最差适配算法是一种内存分配算法,在该算法中,内存分配器(通常是操作系统)程序会找到一个足够大的空闲区域,然后从中分配出所需大小的内存区域。

与最优适配算法和首次适配算法不同,最差适配算法将查找完整个空闲链表,找到一个能够容纳所需内存大小的最大空闲块。这样,在分配内存块时,会剩下较大的未使用内存块。虽然这样做有助于减少内存碎片,但它同时会导致更多的内存被浪费。

以下是一个简单的最差拟合算法程序示例:

#include <stdio.h>
#include <stdlib.h>

#define MAX 1000

typedef struct {
    int addr;
    int size;
} BLOCK;

int used_block[MAX];
BLOCK mem_blocks[MAX];

int cmpfunc (const void * a, const void * b) {
    if ( ((BLOCK*)a)->size <  ((BLOCK*)b)->size) return 1;
    if ( ((BLOCK*)a)->size == ((BLOCK*)b)->size &&
         ((BLOCK*)a)->addr <  ((BLOCK*)b)->addr ) return 1;
    return -1;
}

int allocate_memory(int size) {
    int i, j, max = -1, max_idx = -1;

    for (i = 0; i < MAX; ++i) {
        if (used_block[i] == 0 && mem_blocks[i].size >= size) {
            if (mem_blocks[i].size > max) {
                max = mem_blocks[i].size;
                max_idx = i;
            }
        }
    }

    if (max_idx == -1) {
        return -1;
    }

    if (mem_blocks[max_idx].size == size) {
        used_block[max_idx] = 1;
        return mem_blocks[max_idx].addr;
    } else {
        j = 0;
        while (used_block[j] && j < MAX) ++j;

        BLOCK newblock;
        newblock.addr = mem_blocks[max_idx].addr;
        newblock.size = size;

        mem_blocks[max_idx].addr += size;
        mem_blocks[max_idx].size -= size;

        for (i = 0; i < MAX; ++i) {
            if (used_block[i] == 0)
                continue;
            if (cmpfunc(&mem_blocks[i], &newblock) > 0) {
                BLOCK tmp = newblock;
                newblock = mem_blocks[i];
                mem_blocks[i] = tmp;
            }
        }

        mem_blocks[j] = newblock;
        used_block[j] = 1;

        return newblock.addr;
    }
}

void free_memory(int addr) {
    int i, idx = -1;

    for (i = 0; i < MAX; ++i) {
        if (used_block[i] == 1 && mem_blocks[i].addr == addr) {
            idx = i;
            break;
        }
    }

    if (idx == -1) {
        fprintf(stderr, "Error: Invalid memory address %d\n", addr);
        return;
    }

    used_block[idx] = 0;

    int prev = -1, next = -1;

    if (idx > 0 && !used_block[idx - 1]) {
        prev = idx - 1;
    }

    if (idx < MAX - 1 && !used_block[idx + 1]) {
        next = idx + 1;
    }

    if (prev == -1 && next == -1) {
        return;
    } else if (prev == -1) {
        mem_blocks[idx].size += mem_blocks[next].size;
        for (i = next; i < MAX - 1; ++i) {
            used_block[i] = used_block[i + 1];
            mem_blocks[i] = mem_blocks[i + 1];
        }
        used_block[MAX - 1] = 0;
    } else if (next == -1) {
        mem_blocks[prev].size += mem_blocks[idx].size;
        for (i = idx; i < MAX - 1; ++i) {
            used_block[i] = used_block[i + 1];
            mem_blocks[i] = mem_blocks[i + 1];
        }
        used_block[MAX - 1] = 0;
    } else if (prev != -1 && next != -1) {
        if (mem_blocks[prev].size > mem_blocks[next].size) {
            mem_blocks[idx].size += mem_blocks[next].size;
            for (i = next; i < MAX - 1; ++i) {
                used_block[i] = used_block[i + 1];
                mem_blocks[i] = mem_blocks[i + 1];
            }
            used_block[MAX - 1] = 0;
        } else {
            mem_blocks[prev].size += mem_blocks[idx].size;
            for (i = idx; i < MAX - 1; ++i) {
                used_block[i] = used_block[i + 1];
                mem_blocks[i] = mem_blocks[i + 1];
            }
            used_block[MAX - 1] = 0;
        }
    }
}

int main(void) {
    int i;
    for (i = 0; i < MAX; ++i) {
        used_block[i] = 0;
        mem_blocks[i].addr = i * 8;
        mem_blocks[i].size = (MAX - i) * 10;
    }

    allocate_memory(100);
    allocate_memory(200);
    allocate_memory(300);
    allocate_memory(400);

    printf("Allocated blocks:\n");
    for (i = 0; i < MAX; ++i) {
        if (used_block[i]) {
            printf("%d: address=%d size=%d\n", i, mem_blocks[i].addr, mem_blocks[i].size);
        }
    }

    free_memory(8);

    printf("\nAllocated blocks:\n");
    for (i = 0; i < MAX; ++i) {
        if (used_block[i]) {
            printf("%d: address=%d size=%d\n", i, mem_blocks[i].addr, mem_blocks[i].size);
        }
    }

    return 0;
}

该程序使用数组模拟内存分配器,其中每个块包含其地址和大小。allocate_memory()函数将遍历所有空闲块,找到最大的空闲块,并将其分配给请求的内存大小。如果找不到足够大的块,则返回-1。

在释放内存时,free_memory()函数将查找要释放的块并将其标记为未使用。然后它搜索相邻的未使用块,如果找到,则将它们合并为一个更大的块。

该程序通过调用qsort()函数实现用于空闲块的排序。为了使qsort()函数按我们想要的顺序工作,我们必须定义一个自定义的比较函数cmpfunc()。由于要使用结构体数组,我们必须在比较功能中进行指针操作。

结论

最差适配算法是一种在大多数内存管理系统中使用的算法。它可以帮助减少内存碎片,并使寻找可用块的时间最小化。然而,由于该算法会导致更多的内存被浪费,因此它可能不是最佳选择。因此,在实现内存管理器时,程序员应该根据所需的应用程序或系统性能特性选择适当的算法。