33. 简易内存池

91 阅读3分钟

题目描述

  • 请实现一个简易内存池,根据请求命令完成内存分配和释放。
  • 内存池支持两种操作命令,REQUEST和RELEASE,其格式为:
  • REQUEST=请求的内存大小 表示请求分配指定大小内存,如果分配成功,返回分配到的内存首地址;如果内存不足,或指定的大小为0,则输出error。
  • RELEASE=释放的内存首地址 表示释放掉之前分配的内存,释放成功无需输出,如果释放不存在的首地址则输出error。

注意:

  1. 内存池总大小为100字节。
  2. 内存池地址分配必须是连续内存,并优先从低地址分配。
  3. 内存释放后可被再次分配,已释放的内存在空闲时不能被二次释放。
  4. 不会释放已申请的内存块的中间地址。
  5. 释放操作只是针对首地址所对应的单个内存块进行操作,不会影响其它内存块。

输入描述

首行为整数 N , 表示操作命令的个数,取值范围:0 < N <= 100。

接下来的N行, 每行将给出一个操作命令,操作命令和参数之间用 “=”分割。

输出描述

请求分配指定大小内存时,如果分配成功,返回分配到的内存首地址;如果内存不足,或指定的大小为0,则输出error

释放掉之前分配的内存时,释放成功无需输出,如果释放不存在的首地址则输出error。

用例:

输入 输出 说明
2  
REQUEST=10  
REQUEST=20
                
0  
10
                
输入 输出 说明
5
REQUEST=10
REQUEST=20
REQUEST=20
RELEASE=0
REQUEST=20
REQUEST=10
                
0
10
30
0
0
                
第一条指令,申请地址0~9的10个字节内存,返回首地址0
第二条指令,申请地址10~29的20字节内存,返回首地址10
第三条指令,释放首地址为0的内存申请,0~9地址内存被释放,变为空闲,释放成功,无需输出
第四条指令,申请20字节内存,09地址内存连续空间不足20字节,往后查找到3049地址,返回首地址30
第五条指令,申请10字节,0~9地址内存空间足够,返回首地址0
                
#include <iostream>
#include <vector>
#include <string>
#include <map>
using namespace std;

struct MemoryPool
{
    MemoryPool(int size) : m_size(size), m_pool(new int[size])
    {
        for (int i = 0; i < size; i++)
        {
            m_pool[i] = 0;
        }
    }

    ~MemoryPool()
    {
        delete m_pool;
    }

    string request(int size)
    {
        if (size == 0)
            return "error";

        for (int start = 0; start <= m_size - size; start++)
        {
            bool isFree = true;
            for (int i = 0; i < size; i++)
            {
                if (m_pool[start + i] == 1)
                {
                    isFree = false;
                    break;
                }
            }
            if (isFree)
            {
                for (int i = 0; i < size; i++)
                {
                    m_pool[start + i] = 1;
                }
                m_allocated[start] = size;
                return to_string(start);
            }
        }
        return "error";
    }

    string release(int address)
    {
        if (m_allocated.find(address) == m_allocated.end())
            return "error";

        int size = m_allocated[address];
        for (int i = 0; i < size; i++)
        {
            m_pool[i + address] = 0;
        }
        m_allocated.erase(address);
        return "";
    }

private:
    int m_size;
    int* m_pool;
    map<int, int> m_allocated;
};

int main()
{
    int N;
    cin >> N;
    cin.ignore(); // 千万不能忘
    vector<string> res;
    MemoryPool pool(100);
    for (int i = 0; i < N; i++)
    {
        string command;
        getline(cin, command);
        string temp = command.substr(0, 7);
        if (temp == "REQUEST")
        {
            int size = 0;
            sscanf(command.c_str(), "REQUEST=%d", &size);
            res.push_back(pool.request(size));
        }
        else
        {
            int address = 0;
            sscanf(command.c_str(), "RELEASE=%d", &address);
            string ret = pool.release(address);
            if (!ret.empty())
            {
                res.push_back(ret);
            }
        }
    }

    for (const auto it : res)
    {
        cout << it << endl;
    }
    return 0;
}