内存管理
时间限制:C/C++语言 1000MS;其他语言 3000MS
内存限制:C/C++语言 65536KB;其他语言 589824KB
题目描述:
物联网技术的蓬勃发展,各种传感器纷纷出现。小B所在的项目组正在开发一个物联网项目,她们在研究设计一种新的传感器。这种传感器有自己的基本处理单元,具有一定的自主性,能够进行简单的数据收集、处理、存储和传输。为降低系统功耗并保证系统可靠性和可控性,他们要对内存进行基本的管理。研究小组计划开发一个实验性内存管理器,实现对内存的分配、释放和整理。对应的接口为new、del和def,使用语法为:
new size:分配size字节大小的内存块,返回该内存块的句柄handle,size为正整数;
del handle:释放句柄handle指向的内存块;
def:整理内存碎片,将所有已分配内存块按地址从低到高的顺序迁移,使空闲内存碎片在高地址端拼接在一起;
初始内存为 initSize 字节大小的整片空闲内存,编号为 1 到 initSize 。
new size操作中,若存在不小于size的连续空闲内存,则按照小地址优先的原则从空闲内存区域中分配size大小的内存块,标记该内存块状态为已分配,并返回指向该内存块的句柄。若无法分配,则返回空(NULL)。
del handle操作释放由handle标记的内存块,标记被释放的内存状态为空闲。若handle为无效句柄,则返回ILLEGAL_OPERATION。
def 完成内存整理工作,无返回值。
根据设计,每次成功内存分配返回的句柄为一个正整数,从1开始,依次计数。失败的存储分配操作不影响计数。
项目小组将此项任务分配给小B,小B向你求助,你能帮她吗?
输入
输入中有多组测试数据。每组测试数据的第一行为两个正整数T和MaxMem(1<=T<=10000, 1<=MaxMem<=10000),其中T为操作次数,MaxMem为初始内存大小,随后有T行操作指令。
输出
对每组测试数据,按操作顺序输出操作结果。对每个new操作,在单独行中输出结果,成功时输出其返回句柄值,失败则输出NULL。若del操作失败,输出ILLEGAL_OPERATION。def不产生输出。
样例输入
6 10
new 5
new 3
del 1
new 6
def
new 6
样例输出
1
2
NULL
3
Java实现的代码如下:
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Scanner;
/**
*
* @author fangzheng
* @date 2016-09-10
*
* 360笔试题:动态内存管理
*
*/
public class MemoryManager {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while (scan.hasNext()) {
//也可以移出去将输入多个案例作为整体
LinkedList<Block> blocksList = new LinkedList<>();
int blockId = 0;
int m = scan.nextInt();
int maxSize = scan.nextInt();
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < m; i++) {
String input = scan.next();
if (input.equals("new")) {
// 分配内存
String res = allocatMemory(blockId + 1, scan.nextInt(), maxSize,
blocksList);
if (!res.equals("NULL")) {
blockId++;
}
buffer.append(res).append("\n");
} else if (input.equals("del")) {
// 删除已分配内存
String res =releaseMemory(scan.nextInt(), blocksList);
buffer.append(res).append("\n");
} else if (input.equals("def")) {
// 整理内存,将占用内存向低地址移动
arrangeMemory(blocksList);
}
}
System.out.println(buffer.toString());
}
scan.close();
}
/**
* 整理内存,将占用的内存从高地址转移低地址
* @param list
*/
private static void arrangeMemory(LinkedList<Block> list) {
if (list == null || list.isEmpty()) {
return;
}
//System.out.println("内存整理前:" + list);
Iterator<Block> iterator = list.iterator();
while (iterator.hasNext()) {
Block block = iterator.next();
if (block.isFree) {
iterator.remove();
}
}
//System.out.println("内存整理后:" + list);
}
/**
* 释放内存
*
* @param id
* @param list
* @return
*/
private static String releaseMemory(int id, LinkedList<Block> list) {
boolean hasRelease = false;
for (Block block : list) {
if (block.id == id) {
block.isFree = true;
hasRelease = true;
break;
}
}
return hasRelease ? "" : "ILLEAG_OPERATION";
}
/**
* 分配内存
*
* @param id
* @param needSize
* @param maxSize
* @param list
* @return
*/
private static String allocatMemory(int id, int needSize, int maxSize,
LinkedList<Block> list) {
if (needSize <= 0 || needSize > maxSize) {
return "NULL";
}
int temp = 0;
int sumSize = 0;
int i = 0;
int defaultId = 0;
for (; i < list.size(); i++) {
Block block = list.get(i);
if (block.isFree && block.size >= needSize) {
temp = block.size - needSize;
block.size = needSize;
block.isFree = false;
defaultId = block.id;
block.id = id;
break;
}
sumSize += block.size;
}
if (i < list.size()) {
if (temp > 0) {
// 在上面的Block后面连接上大小位temp的block
Block otherBlock = new Block(defaultId, temp, false);
list.add(i, otherBlock);
}
} else if (needSize <= maxSize - sumSize) {
Block block = new Block(id, needSize, false);
list.add(i, block);
} else {
return "NULL";
}
return id + "";
}
}
class Block {
int id;//分配的内存块序号
int size;//分配大小
boolean isFree;//内存块状态
public Block(int id, int size, boolean isFree) {
this.id = id;
this.size = size;
this.isFree = isFree;
}
@Override
public String toString() {
return "Block [id=" + id + ", size=" + size + ", isFree=" + isFree
+ "]";
}
}