华为OD 简易内存池 C++

简易内存池

题目描述

请实现一个简易内存池,根据请求命令完成内存分配和释放。

内存池支持两种操作命令,REQUEST和RELEASE,其格式为:

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

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

注意:

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

输入描述

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

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

输出描述

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

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

用例1

输入

2
REQUEST=10
REQUEST=20

输出

0
10

用例2

输入

5
REQUEST=10
REQUEST=20
RELEASE=0
REQUEST=20
REQUEST=10

输出

0
10
30
0

说明

第一条指令,申请地址0~9的10个字节内存,返回首地址0

第二条指令,申请地址10~29的20字节内存,返回首地址10

第三条指令,释放首地址为0的内存申请,0~9地址内存被释放,变为空闲,释放成功,无需输出

第四条指令,申请20字节内存,09地址内存连续空间不足20字节,往后查找到3049地址,返回首地址30

第五条指令,申请10字节,0~9地址内存空间足够,返回首地址0

解析

知识点:

磁盘空闲分区管理

在操作系统中,空闲分区表和空闲分区链是磁盘管理中的两个重要概念,用于记录磁盘上可用的空闲空间。

  1. 空闲分区表(Free Space Table):

    • 空闲分区表是一个数据结构,用于记录磁盘上各个分区的空闲空间情况。
    • 通常,空闲分区表会列出每个分区的起始位置、大小和是否空闲等信息。
    • 空闲分区表的更新通常在分配或释放空间时进行,以确保其准确反映了磁盘的空闲空间情况。
  2. 空闲分区链(Free Space List):

    • 空闲分区链是一种数据结构,用于维护磁盘上空闲空间的逻辑顺序。
    • 空闲分区链中的每个节点表示一个连续的空闲区域,节点间通过指针连接起来。
    • 当需要分配空间时,操作系统可以遍历空闲分区链以找到满足分配要求的空闲区域,然后进行分配。
    • 分配或释放空间时,空闲分区链也需要相应地更新,确保链表的连续性和正确性。
  3. 位视图法

    使用标志为1 未使用标志为0

C++

#include <iostream>
#include <sstream>
#include <unordered_map>
#include <vector>
#include <algorithm>

using namespace std;

const int MEMORY_POOL_SIZE = 100;

class MemoryPool {
private:
    char memory[MEMORY_POOL_SIZE];
    unordered_map<int, int> allocated;      //已经分配的分区表
    vector<pair<int, int>> freeBlocks;      //空闲分区表

public:
    MemoryPool() {
        freeBlocks.push_back({0, MEMORY_POOL_SIZE});
    }

    string requestMemory(int size) {
        if (size <= 0) {
            return "error";
        }

        for (auto& block : freeBlocks)
        {
            if (block.second >= size) {
                int startIndex = block.first;
                block.first += size;
                block.second -= size;

                if (block.second == 0) {
                    freeBlocks.erase(remove_if(freeBlocks.begin(), freeBlocks.end(), 
                        [&block](const auto& b){ return b == block; }), freeBlocks.end());
                }

                allocated[startIndex] = size;
                return to_string(startIndex);
            }
        }

        return "error";
    }

    string releaseMemory(int startIndex) {
        auto it = allocated.find(startIndex);
        if (it == allocated.end()) {
            return "error";
        }

        int size = it->second;
        allocated.erase(it);
        addFreeBlock(startIndex, size);
        return "";
    }

    void addFreeBlock(int startIndex, int size) {
        auto it = freeBlocks.begin();
        while (it != freeBlocks.end() && it->first < startIndex) {      //找到插入的位置
            ++it;
        }

        if (it != freeBlocks.begin() && prev(it)->first + prev(it)->second == startIndex) {
            prev(it)->second += size;
            startIndex = prev(it)->first;
            size = prev(it)->second;
            freeBlocks.erase(prev(it));
        }

        if (it != freeBlocks.end() && startIndex + size == it->first) {
            it->first = startIndex;
            it->second += size;
        } else {
            freeBlocks.insert(it, {startIndex, size});
        }
    }

    string processCommand(const string& command) {
        stringstream ss(command);
        string operation, value;
        getline(ss, operation, '=');
        getline(ss, value);

        if (operation == "REQUEST") {
            int size = stoi(value);
            string result = requestMemory(size);
            return result;
        } else if (operation == "RELEASE") {
            int startIndex = stoi(value);
            return releaseMemory(startIndex);
        } else {
            return "Invalid operation";
        }
    }
};

int main() {
    int N;
    cin >> N;
    cin.ignore(); // Ignore the newline character after N

    MemoryPool memoryPool;

    for (int i = 0; i < N; ++i) {
        string command;
        getline(cin, command);
        string result = memoryPool.processCommand(command);
        cout << result << endl;
    }

    return 0;
}

  • 20
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值