提示:文章
文章目录
前言
前期疑问:
本文目标:
一、背景
二、题目
简易内存池
请实现一个简易内存池,根据请求命令完成内存分配和释放。请实现以下接口:
MemSystem(int space) - 系统初始化,内存池总大小为 space。
request(int size) - 请求分配指定大小内存,如果分配成功,返回分配到的内存首地址;如果内存不足,或指定的大小为0,则输出 -1
release(int addr) - 释放掉之前分配的内存,释放成功返回 true;如果释放不存在的首地址,则返回 false
注意:
1.内存池地址分配必须是连续内存,并优先从低地址分配。
2.内存释放后可被再次分配,已释放的内存在空闲时不能被二次释放。
3.不会释放已申请的内存块的中间地址。
4.释放操作只是针对首地址所对应的单个内存块进行操作,不会影响其它内存块。
输入
每行表示一个函数调用,初始化函数仅首行调用一次,累计函数调用不超过 100 次。
输出
答题时按照函数/方法原型中的要求(含返回值)进行实现,输出由框架完成(其中首行固定输出 null)
样例1
输入:
MemSystem(100)
request(10)
request(20)
release(0)
request(20)
request(10)
输出:
null
0
10
true
30
0
解释:
request(10):申请地址0~9的10个字节内存,返回首地址0
request(20):申请地址10~29的20字节内存,返回首地址10
release(0): 释放首地址为0的内存申请,0~9地址内存被释放,变为空闲,释放成功,无需输出
request(20):申请20字节内存,0~9地址内存连续空间不足20字节,往后查找到30~49地址,返回首地址30
request(10):申请10字节,0~9地址内存空间足够,返回首地址0
样例2
输入:
MemSystem(4)
request(3)
request(2)
release(3)
release(0)
request(2)
request(0)
输出:
null
0
-1
false
true
0
-1
解释:
无
题目代码框架
main.c文件
cpp
#include <stdio.h>
#include "securec.h"
#include "solution.c"
// 以下为考题输入输出框架,此部分代码不建议改动;提交代码时请勿包含下面代码
static void SkipWs(void)
{
char c = (char)getchar();
while (c == ' ' || c == '\r' || c == '\n') {
c = (char)getchar();
}
(void)ungetc(c, stdin);
}
static bool CallCreate(MemSystem **sys)
{
int space = 0;
bool isOk = false;
do {
SkipWs();
char c = (char)getchar();
if (c != '(') { break; }
if (scanf_s("%d", &space) != 1) { break; }
SkipWs();
c = (char)getchar();
if (c != ')') { break; }
isOk = true;
*sys = MemSystemCreate(space);
} while (false);
printf("null\n");
return isOk;
}
static bool CallRequest(MemSystem *sys)
{
int size = 0;
int returnValue = 0;
bool isOk = false;
do {
SkipWs();
char c = (char)getchar();
if (c != '(') { break; }
if (scanf_s("%d", &size) != 1) { break; }
SkipWs();
c = (char)getchar();
if (c != ')') { break; }
isOk = true;
returnValue = MemSystemRequest(sys, size);
printf("%d", returnValue);
} while (false);
printf("\n");
return isOk;
}
static bool CallRelease(MemSystem *sys)
{
int addr = 0;
bool returnValue = false;
bool isOk = false;
do {
SkipWs();
char c = (char)getchar();
if (c != '(') { break; }
if (scanf_s("%d", &addr) != 1) { break; }
SkipWs();
c = (char)getchar();
if (c != ')') { break; }
isOk = true;
returnValue = MemSystemRelease(sys, addr);
printf("%s", returnValue ? "true" : "false");
} while (false);
printf("\n");
return isOk;
}
static bool GetCmdName(char* buffer, size_t size)
{
SkipWs();
size_t pos = 0;
char c = (char)getchar();
while (c != '\r' && c != '\n' && c != ' ' && c != '(' && feof(stdin) == 0 && pos < size) {
buffer[pos++] = c;
c = (char)getchar();
}
if (pos >= size) { return false; }
buffer[pos] = '\0';
if (pos == 0) { return feof(stdin) != 0; }
if (feof(stdin) == 0) { (void)ungetc(c, stdin); }
return true;
}
int main(void)
{
char cmd[64] = {0};
bool isOk = GetCmdName(cmd, sizeof(cmd));
MemSystem *sys = NULL;
if (strcmp(cmd, "MemSystem") != 0) { isOk = false; }
if (isOk) { isOk = CallCreate(&sys); }
while (isOk) {
const char *cmds[] = {"request", "release"};
bool (*funcs[])(MemSystem *sys) = {CallRequest, CallRelease};
if (!GetCmdName(cmd, sizeof(cmd))) {
isOk = false;
break;
}
if (cmd[0] == '\0') {
MemSystemFree(sys);
return 0;
}
isOk = false;
for (size_t i = 0; i < sizeof(cmds) / sizeof(cmds[0]); ++i) {
if (strcmp(cmd, cmds[i]) == 0) {
isOk = (*funcs[i])(sys);
break;
}
}
}
printf("Error: Input format incorrect!");
if (sys) { MemSystemFree(sys); }
return 0;
}
solution.c文件
c
#include <stdbool.h>
typedef struct {
} MemSystem;
// 注意:该函数为类构造函数,返回的对象指针将作为其他待实现函数的入参;框架代码在调用该函数后,会输出 null(而非指针)
static MemSystem *MemSystemCreate(int space)
{
return NULL;
}
static int MemSystemRequest(MemSystem *sys, int size)
{
return 0;
}
static bool MemSystemRelease(MemSystem *sys, int addr)
{
return false;
}
static void MemSystemFree(MemSystem *sys)
{
}
三、解题
第一版代码
感觉这版代码就是东拼西凑的代码,竟然还通过了两个题目测试用例。
cpp
#include <stdbool.h>
#include <stdio.h>
#include <malloc.h>
#include "securec.h"
typedef struct {
int start;
int end;
} MemoryUint;
typedef struct {
bool status;
int index;
} HashMap;
typedef struct {
MemoryUint memoryUint[101];
HashMap hashMap[101];
int hashCount;
int unitCount;
int memLeftSize;
int totalMemorySize;
} MemSystem;
static int compare(const void* a, const void* b)
{
return ((HashMap*)a)->index - ((HashMap*)b)->index;
}
// 注意:该函数为类构造函数,返回的对象指针将作为其他待实现函数的入参;框架代码在调用该函数后,会输出 null(而非指针)
static MemSystem *MemSystemCreate(int space)
{
MemSystem* sys = (MemSystem*)malloc(sizeof(MemSystem));
if (sys == NULL) {
return NULL;
}
memset_s(sys->memoryUint, sizeof(sys->memoryUint), 0, sizeof(sys->memoryUint));
memset_s(sys->hashMap, sizeof(sys->hashMap), 0, sizeof(sys->hashMap));
sys->totalMemorySize = space;
sys->memLeftSize = space;
sys->hashCount = 0;
sys->unitCount = 0;
return sys;
}
static int MemSystemRequest(MemSystem *sys, int size)
{
if(size == 0)
{
return -1;
}
if(sys->hashCount == 0)
{
sys->memoryUint[0].start = 0;
sys->memoryUint[0].end = sys->memoryUint[0].end + size;
sys->hashMap[0].status = true;
sys->hashMap[0].index = sys->memoryUint[0].start;
sys->hashCount += 1;
return sys->memoryUint[0].start;
}
for(int i = 0; i < sys->hashCount; i++)
{
if(sys->hashMap[i].status == true)
{
int spareMemSize = 0;
if(sys->hashCount == 1)
{
if(sys->memoryUint[sys->hashMap[0].index].start > size)
{
sys->memoryUint[0].start = 0;
sys->memoryUint[0].end = sys->memoryUint[0].start + size;
sys->hashMap[sys->hashCount].status = true;
sys->hashMap[sys->hashCount].index = sys->memoryUint[0].start;
sys->hashCount += 1;
qsort(sys->hashMap, sys->hashCount, sizeof(HashMap), compare);
return sys->memoryUint[0].start;
}
spareMemSize = sys->totalMemorySize - sys->memoryUint[sys->hashMap[0].index].end;
}
else
{
if(sys->memoryUint[sys->hashMap[0].index].start >= size)
{
sys->memoryUint[0].start = 0;
sys->memoryUint[0].end = sys->memoryUint[0].start + size;
sys->hashMap[sys->hashCount].status = true;
sys->hashMap[sys->hashCount].index = sys->memoryUint[0].start;
sys->hashCount += 1;
qsort(sys->hashMap, sys->hashCount, sizeof(HashMap), compare);
return sys->memoryUint[0].start;
}
int lastMemInfo = 0;
if(sys->hashMap[i + 1].status == false)
{
lastMemInfo = sys->totalMemorySize;
} else
{
lastMemInfo = sys->hashMap[i + 1].index;
}
spareMemSize = lastMemInfo - sys->memoryUint[sys->hashMap[i].index].end;
}
if(spareMemSize >= size)
{
sys->memoryUint[sys->memoryUint[sys->hashMap[i].index].end].start = sys->memoryUint[sys->hashMap[i].index].end;
sys->memoryUint[sys->memoryUint[sys->hashMap[i].index].end].end = sys->memoryUint[sys->memoryUint[sys->hashMap[i].index].end].start + size;
sys->hashMap[sys->hashCount].status = true;
sys->hashMap[sys->hashCount].index = sys->memoryUint[sys->memoryUint[sys->hashMap[i].index].end].start;
sys->hashCount += 1;
return sys->memoryUint[sys->memoryUint[sys->hashMap[i].index].end].start;
}
}
}
return -1;
}
static bool MemSystemRelease(MemSystem *sys, int addr)
{
for(int i = 0; i < sys->hashCount; i++)
{
if(sys->hashMap[i].status == true)
{
if(sys->memoryUint[sys->hashMap[i].index].start == addr)
{
sys->hashMap[i].status = false;
sys->hashMap[i].index = 0;
for(int j = i; j < sys->hashCount; j++)
{
bool status = sys->hashMap[j + 1].status;
int index = sys->hashMap[j + 1].index;
sys->hashMap[j].status = status;
sys->hashMap[j].index = index;
}
sys->hashCount -= 1;
return true;
}
}
}
return false;
}
static void MemSystemFree(MemSystem *sys)
{
free(sys);
}
尝试全例执行代码,下面的用例没有通过。
用例1
shell
输入:
MemSystem(100)
request(10)
request(20)
request(30)
request(40)
预期输出:
null
0
10
30
60
实际错误输出
shell
null
0
10
30
-1
这个测试用例没有通过是因为
cpp
if(spareMemSize > size)
// 需要改成
if(spareMemSize >= size)
修改后上述测试用例通过,但是下面的测试用例失败
shell
输入:
MemSystem(100)
request(10)
request(20)
request(30)
request(40)
release(30)
request(10)
request(10)
request(10)
预期输出:
null
0
10
30
60
true
30
40
50
实际错误输出为
shell
null
0
10
30
60
true
30
30
30
总结
未完待续