当前位置:编程学习 > C/C++ >>

内存的连续分配与回收算法

说明:
部分代码参考《数据结构》书。
1、采用空闲分区链链接空闲分区,用循环首次适应算法分配内存。
 
2、假定内存块的大小、地址以“字”为单位计。空闲区、作业区边界采用标识。
“字”的数据结构如下:
leftLink
tag
size
rightLink
空闲空间
upLink
tag
 
 
3、分配内存时,将符合要求的空闲区的高地址部分分配给作业,以减少修改指针的操作。
 
4、源程序:
[cpp] 
// 空闲分区链,边界标识法 
// 循环首次适应算法 
 
#define _CRT_SECURE_NO_WARNINGS 
#define NDEBUG 
#include <iostream> 
#include <map> 
#include <string> 
#include <cstdio> 
#include <cstdlib> 
#include <cassert> 
using namespace std; 
 
const int MIN_REMAIN  = 3;      // 不保留<=MIN_REMAIN的剩余量 
const int MEMORY_SIZE = 128;    // 内存空间大小(以字计) 
 
enum State{FREE, ALLOC};        // 块标志:空闲FREE,占用ALLOC 
 
struct Word { 
    union { 
        Word *leftLink;         // 头部:指向前驱结点 
        Word *upLink;           // 尾部:指向本结点头部 
    }; 
    State tag;                  // 头部、尾部:都设块标志 
    unsigned int size;          // 头部:块大小 
    Word *rightLink;            // 头部:指向后继结点 
 
    // 默认构造函数 
    Word() 
        :leftLink(NULL),        // 共用体只初始化一个成员即可 
        tag(FREE), 
        size(0), 
        rightLink(NULL){} 
}memory[MEMORY_SIZE];           // 假设内存总量为MEMORY_SIZE个字 
 
struct Job { 
    string name; 
    unsigned int size; 
}; 
 
// 返回front所指向结点的尾部的地址。 
inline Word * FootLoc(Word *front)  // inline? 

    return front + front->size - 1; 

 
// 初始只有一块空闲区,初始化它的首字和尾部,pav指向首字。 
// 建立双向循环链表,不带头结点。 
void Initiate(Word *&pav) 

    pav = memory;   // 表中不设表头结点,表头指针pav可以指向表中任一结点 
 
    // 头部 
    pav->leftLink = memory; 
    pav->rightLink = memory; 
    pav->size = MEMORY_SIZE; 
    pav->tag = FREE; 
 
    // 尾部 
    FootLoc(pav)->upLink = memory; 
    FootLoc(pav)->tag = FREE; 

 
// 若有不小于n的空闲块,则分配相应的存储块,并返回其首地址; 
// 否则返回NULL。 
// 若分配后可利用空间表不空,则pav指向表中刚分配过的结点的后继结点。 
// n应>=3,包括头尾两个字,而实际分配时忽略不计? 
Word * AllocBoundTag (Word *&pav, unsigned int n) 

    if (n <= 2)  { 
        cout << "n<=2,不能分配空间!" << endl; 
        return NULL; 
    } 
    Word *p = NULL; 
    for (p = pav; 
        NULL != p && p->size < n && p->rightLink != pav; 
        p = p->rightLink);           // 查找不小于n的空闲块 
    if (NULL == p || p->size < n) 
    { 
        cout << "内存可用空间不够,请先释放内存。" << endl; 
        return NULL;                // 找不到,返回空指针 
    } 
 
    // p指向找到的空闲块 
    Word *f = FootLoc(p);           // 指向底部 
    pav = p->rightLink;              // “循环”:pav指向*p结点的后继结点 
    if (p->size - n <= MIN_REMAIN) {  // 整块分配,不保留<=MIN_REMAIN的剩余量 
        if (pav == p) { 
            pav = NULL;             // 可利用空间表变为空表 
        } 
        else {                      // 在表中删除分配的结点 
            pav->leftLink = p->leftLink; 
            p->leftLink->rightLink = pav; 
        } 
        p->tag = ALLOC; 
        f->tag = ALLOC;              // 修改分配结点的头部和底部标志 
    } 
    else {                          // 分配该块的后n个字使剩余块头部:leftLink, tag, rightLink不变 
        f->tag = ALLOC;              // 分配块尾部:tag 
        //f->upLink = FootLoc(p) + 1;    // 分配块尾部:upLink 
        p->size -= n;               // 剩余块头部:size 
        // 剩余块头部:leftLink, tag, rightLink不变 
        f = FootLoc(p);             // f指向剩余块尾部 
        f->tag = FREE;               // 剩余块尾部:tag 
    &n

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,