2024-7-9 简易内存池

题目解析:

1.哪些内存被占用了?

2.怎么按照要求释放内存?

要想知道那些内存被占用了,我们可以使用一个数组来模拟内存池,初始化大小为100,其中的状态分为已占用或者空缺,用true和false表示状态。

true:内存被占用

false:内存未被占用

故初始化一个数组,数组中存放位置是否被占用,即vector<bool> status=vector<bool>(100, false)

现在已经解决了第一个问题,接下来是第二个问题,如何删除指定空间大小的内存?

延续上面的思路,若释放内存则直接将状态改为false即可,那怎么知道从哪个位置开始,到哪个位置结束,将指定位置的值更改呢?我们可以使用map来解决这个问题,map<key,value>中key可以用来记录起始位置,value表示其后有多少空间,在删除时,只需要先访问指定位置上的元素是否被使用,未被使用返回error,已被使用,则将status中的位置改为true,这样就完成了释放资源的操作。

上述的问题都解决完之后,此时考虑我们如何分配内存,遵循题目中连续的原则,则存在的问题即是若前面已经被释放但是不满足要求,该如何跳过该段内存,继续向后寻找。将此问题抽象为寻找从某一位置开始中间连续size大小的内存。

具体实现代码如下

#include<iostream>
#include<vector>
#include<sstream>
#include<map>
using namespace std;


class MemPool {
public:
    //构造函数
    MemPool() {
        //初始化内存
        status = vector<bool>(100, false);
    }

    int Request(int size) {  // 要求分配多少字符
        int res = -1;
        if (size <= 0) {
            return res;
        }
        //寻找位置插入
        for (int i = 0; i < total - size; i++) {
            int j = 0;
            while (j < size) {
                if (status[i+j]) {
                    break;
                }
                j++;
            }
            if (j == size) {
                res = i;
                break;
            }
        }

        //判断res的值
        if (res == -1) {
            return res;
        }

        for (int i = 0; i < size; i++) {
            status[i+res] = true;
        }
        storage[res] = size;
        return res;
    }

    bool Release(int startAddr) {
        //判断内存是否被使用
        if (status.count(startAddr)) {
            return false;
        }

        for (int i = startAddr; i < storage[startAddr]; i++) {
            status[i] = false;
        }
        return true;
    }
private:
    vector<bool> status;
    map<int, int> storage;
    static constexpr int total = 100;
};



int main() {
    int N;
    cin >> N;

    MemPool pool;
    for (int i = 0; i < N; ++i) {
        string str;
        cin >> str;

        string cmd = str.substr(0, str.find_first_of('='));
        int num = stoi(str.substr(str.find_first_of('=') + 1));
        if (cmd == "REQUEST") {
            int size = num;
            int result = pool.Request(size);
            if (result != -1) {
                cout << result << endl;
            }
            else {
                cout << "error" << endl;
            }
        }
        else {
            int addr = num;
            if (!pool.Release(addr)) {
                cout << "error" << endl;
            }
        }
    }

    return 0;
}

综上所述,应该掌握两个点,一个是合理使用各种结构,一开始只想着用数组完成,并没有考虑到map,所以浪费了大量时间在寻找插入位置上,另外一个就是学习如何查找i之后大小为size的空间。

仅用作学习用途,便于复习。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值