简易内存池(中)
提示:文章
文章目录
- 前言
- 一、背景
- 二、
- 第二版代码
- 用例2
- 用例3
- 用例4
- 用例5
- 总结
前言
前期疑问:
本文目标:
一、背景
最近
二、
针对上述失败用例,修改代码如下
第二版代码
#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;
if (sys->hashMap[i + 1].status == false) {
sys->hashMap[i + 1].status = true;
sys->hashMap[i + 1].index = sys->memoryUint[sys->memoryUint[sys->hashMap[i].index].end].start;
} else {
// 在中间申请内存,hash表中间插入一个key值
for (int j = sys->hashCount - 1; j > i; j--) {
bool status = sys->hashMap[j].status;
int index = sys->hashMap[j].index;
sys->hashMap[j + 1].status = status;
sys->hashMap[j + 1].index = index;
}
sys->hashMap[i + 1].status = true;
sys->hashMap[i + 1].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->hashMap[sys->hashCount].status = false;
sys->hashMap[sys->hashCount].index = 0;
sys->hashCount -= 1;
return true;
}
}
}
return false;
}
static void MemSystemFree(MemSystem* sys)
{
free(sys);
}
可以通过上述用例,下面用例执行失败
用例2
输入:
MemSystem(100)
request(200)
预期输出:
null
-1
实际错误输出
null
0
在MemSystemRequest函数中增加下述代码,可以解决上述用例失败问题
if(sys->totalMemorySize < size)
{
return -1;
}
执行用例,下述用例失败
用例3
MemSystem(100)
request(40)
request(30)
request(20)
request(10)
release(0)
release(40)
release(90)
request(70)
预期输出:
null
0
40
70
90
true
true
true
0
实际错误输出
null
0
40
70
90
true
true
true
-1
经过调试发现该行代码有问题,并修改可以解决上述用例失败问题。原因是应该是大于等于就可以申请内存。
if (sys->hashCount == 1) {
if (sys->memoryUint[sys->hashMap[0].index].start > size) {
// 改成
if (sys->hashCount == 1) {
if (sys->memoryUint[sys->hashMap[0].index].start >= size) {
下述用例失败
用例4
MemSystem(100)
request(40)
request(30)
request(20)
request(10)
release(0)
release(40)
release(90)
request(80)
release(70)
request(80)
release(0)
request(40)
request(60)
预期输出:
null
0
40
70
90
true
true
true
-1
true
0
true
0
40
实际错误输出
null
0
40
70
90
true
true
true
-1
true
0
true
0
-1
调试代码发现memoryUnit成员中的数据没有清空,可能会对后面的逻辑处理有影响,在MemSystemRelease函数中增加清空操作
if (sys->memoryUint[sys->hashMap[i].index].start == addr) {
sys->hashMap[i].status = false;
sys->hashMap[i].index = 0;
// 改成
if (sys->memoryUint[sys->hashMap[i].index].start == addr) {
sys->memoryUint[sys->hashMap[sys->hashCount].index].start = 0;
sys->memoryUint[sys->hashMap[sys->hashCount].index].end = 0;
sys->hashMap[i].status = false;
sys->hashMap[i].index = 0;
可以解决上述问题
执行代码下述测试用例错误
用例5
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
实际错误输出
null
0
10
30
60
true
10
30
40
调试代码发现MemoryUnit中的数据有的被清除了,检查代码发现刚才家的几行代码有问题。修改成下述形式可以解决这个问题
sys->memoryUint[sys->hashMap[sys->hashCount].index].start = 0;
sys->memoryUint[sys->hashMap[sys->hashCount].index].end = 0;
// 改成
sys->memoryUint[sys->hashMap[i].index].start = 0;
sys->memoryUint[sys->hashMap[i].index].end = 0;
再次执行代码成功
总结
未完待续