当前位置: 首页 > article >正文

简易内存池(中)

提示:文章

文章目录

  • 前言
  • 一、背景
  • 二、
    • 第二版代码
    • 用例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;

再次执行代码成功


总结

未完待续


http://www.kler.cn/a/460515.html

相关文章:

  • linux 软链接 快捷方式 详解
  • OpenHarmony通过挂载镜像来修改镜像内容,RK3566鸿蒙开发板演示
  • SpringCloud源码分析-Lettue Redis
  • 机器学习-感知机-神经网络-激活函数-正反向传播-梯度消失-dropout
  • 【C语言】可移植性陷阱与缺陷(三):整数的大小
  • 工厂模式与抽象工厂模式在Unity中的实际应用案例
  • Kubernetes: NetworkPolicy 的实践应用
  • 航顺芯片推出HK32A040方案,赋能汽车矩阵大灯安全与智能化升级
  • Linux postgresql-15部署文档
  • 音频进阶学习九——离散时间傅里叶变换DTFT
  • 华为仓颉编程语言的函数与结构类型分析
  • Midjourney技术浅析(五):图像细节处理
  • 【大模型实战篇】GLM-Zero模型初代版本的尝鲜
  • SSM-Spring-IOC/DI对应的配置开发
  • 【Win】感觉“ctypes.WinDLL(“user32“)“跟“ctypes.windll.user32“看起来很像呀,它们之间有什么区别呢?
  • UL-SCH 处理函数
  • 关于今天发现的一个bug
  • 深入解析Android JNI:以Visualizer为例
  • Ragas自动化评测整体后端流程
  • 平凡的2024回顾
  • 【每日学点鸿蒙知识】广告ID、NFC手机充值、CSS支持语法、PC与模拟器交互、SO热更新等
  • 前端实现PDF预览的几种选择(pdfjs-dist、react-pdf、pdf-viewer)
  • 嵌入式科普(25)Home Assistant米家集成意味着IOT的核心是智能设备
  • 形象地理解UE4中的数据结构 TLinkedListBase
  • [极客大挑战 2019]LoveSQL 1解题思路
  • Java多线程中,synchronized和ReentrantLock的区别是什么?及使用场景有哪些?