使用链表记录已分配的内存起始地址和大小,后续分配和释放基于此链表
cpp
#include <iostream>
#include <string>
#include <algorithm>
#include <list>
using namespace std;
// 简易内存池
static void HuaWei_OD_test25(void)
{
// 请求分配指定大小内存时,如果分配成功,返回分配到的内存首地址;
// 如果内存不足,或指定的大小为0,则输出error。
// 释放掉之前分配的内存时,释放成功无需输出,如果释放不存在的首地址则输出error。
int cmd_cnt;
cin >> cmd_cnt;
#define REQUEST_CMD 0
#define RELEASE_CMD 1
// 命令序列,这里pair的first代表了命令类型,0为申请,1为释放
// pair的second,对于request代表了申请内存的大小,
// 对于release代表了释放内存的首地址
vector<pair<int, int>> cmd_vec;
for (int i = 0; i < cmd_cnt; i++)
{
string cmd;
cin >> cmd;
auto find_delim = cmd.find('=', 0);
string val_str = cmd.substr(find_delim + 1, -1);
int val = atoi(val_str.c_str()); // 获得值
if (cmd.find("REQUEST") != string::npos)
{
// 内存申请命令
cmd_vec.push_back(std::make_pair(REQUEST_CMD, val));
}
else if (cmd.find("RELEASE") != string::npos)
{
// 内存释放命令
cmd_vec.push_back(std::make_pair(RELEASE_CMD, val));
}
}
// 记录成功分配的内存首地址和大小
struct little_mem
{
int start_addr;
int size;
};
list<little_mem> mem_allocate_list;
for (int i = 0; i < cmd_vec.size(); i++)
{
// 释放操作
if (cmd_vec[i].first == RELEASE_CMD)
{
// 释放不存在的首地址输出 error
auto match_pos = std::find_if(
mem_allocate_list.begin(), mem_allocate_list.end(),
[=](const little_mem &mem)
{
if (mem.start_addr == cmd_vec[i].second)
return true;
return false; });
// 当内存成功申请列表为空,或者找不到此命令对应内存的起始地址
if (mem_allocate_list.empty() || match_pos == mem_allocate_list.end())
{
cout << "error\n";
}
else
{
// 成功释放,将对应申请内存记录从mem_allocate_list排除
mem_allocate_list.erase(match_pos);
}
}
// 申请操作
else if (cmd_vec[i].first == REQUEST_CMD)
{
// 如果申请内存大小为0,输出error
if (cmd_vec[i].second == 0)
{
cout << "error\n";
}
// 当此时申请内存大小超出限制,输出error
if (cmd_vec[i].second > 100)
{
cout << "error\n";
}
int start_base = 0; // 内存申请起始地址
for (const auto &mem : mem_allocate_list)
{
// 如果[start_base, start_base + cmd_vec[i].second]
// 与[mem.start_addr, mem.start_addr + mem.size]
// 有重合则start_base向后移
// 区域交叉情况1
bool cross_1 = (start_base + cmd_vec[i].second > mem.start_addr &&
start_base + cmd_vec[i].second <= mem.start_addr + mem.size);
// 区域交叉情况2
bool cross_2 = (start_base >= mem.start_addr &&
start_base <= mem.start_addr + mem.size);
if (cross_1 || cross_2)
{
start_base = mem.start_addr + mem.size;
}
}
if (start_base + cmd_vec[i].second < 100)
{
cout << start_base << endl;
little_mem new_mem;
new_mem.start_addr = start_base;
new_mem.size = cmd_vec[i].second;
mem_allocate_list.push_back(new_mem);
}
}
}
}
int main()
{
HuaWei_OD_test25();
return 0;
}