超级好用的C++实用库之动态内存池

简介: 超级好用的C++实用库之动态内存池

概述

动态内存池是一种内存管理技术,主要用于提高程序在频繁进行小块内存分配和释放时的效率。相比于传统的malloc/free、new/delete、或其他动态内存分配函数,内存池预先申请一大块连续内存,并将这块大内存分割成多个固定大小或一定范围大小的小内存块,然后以池的方式管理和分发这些小内存块。

内存池一般包括:初始化、分配内存块、回收内存块以及整体释放等功能模块。具体实现时,可以通过数组、链表或树等多种数据结构来组织和追踪空闲内存块的状态。当请求分配内存时,从池中取出一个空闲块。当内存不再使用时,将其归还到内存池中,以便后续复用。

CHP_DynamicMemPool类

在C++中,并没有内置的内存池类。为了方便应用层使用内存池,我们封装了CHP_DynamicMemPool类。CHP_DynamicMemPool类是对动态内存池的封装,适用于需要频繁使用内存块,内存块的总数相对固定,但每个内存块的大小不一样的场景,一般会结合队列使用。CHP_DynamicMemPool类的头文件,可参考下面的示例代码。

#pragma once

#include <list>

#include "HP_Mutex.h"

class CHP_DynamicMemPool
{
public:
    CHP_DynamicMemPool();
    ~CHP_DynamicMemPool();

    void Init(unsigned int uiMaxBlockCount, bool bNeedLock = true);

    char *Alloc(unsigned int uiBytes);

    void Release(char *pBuf);

    void Reset();

    unsigned int GetTotalBlockCount();

    void GetCurBlockCount(unsigned int &uiUsedCount, unsigned int &uiFreeCount);

private:
    typedef struct _TDynamicMemBlock 
    {
        char *pBlock;
        unsigned int uiBlockLen;
    }TDynamicMemBlock;

    typedef std::list<TDynamicMemBlock> TDynamicMemBlockList;

    unsigned int m_uiMaxBlockCount;
    bool m_bNeedLock;
    TDynamicMemBlockList m_listUsed;
    TDynamicMemBlockList m_listFree;
    CHP_Mutex m_mutexBlockList;
};

CHP_DynamicMemPool类有6个公共成员函数,下面逐一进行介绍。

Init:初始化内存池,内存池中含有多个内存块,每个内存块的大小可能不一样。参数uiMaxBlockCount为内存块的最大个数,分配内存时,如果超过内存块的最大个数,则分配失败;参数bNeedLock表示是否需要加锁,默认值为true,如果应用层使用CHP_DynamicMemPool对象时已经加了锁,这里可以传入false。

Alloc:分配指定大小的buffer。内存池中含有一个已使用队列和一个空闲队列,分配buffer时,先从空闲队列中查找是否有符合条件的内存块。如果有,直接返回该内存块;如果没有,则检查所有内存块的数量是否超过内存块的最大个数。如果没有超过,则新建一个合适大小的内存块,并加入已使用队列中。如果超过,且空闲队列非空,则从空闲队列取一个内存块,并重新分配合适大小的内存。参数uiBytes为buffer的大小,单位为字节。返回非NULL表示成功,否则失败。

Release:释放buffer,将其从已使用队列放入到空闲队列中。参数pBuf为之前分配的的buffer指针。

Reset:重置内存池,会释放所有内存块中的内存。

GetTotalBlockCount:获取所有内存块的数量。

GetCurBlockCount:获取已使用内存块和空闲内存块的数量。参数uiUsedCount为已使用内存块的数量,参数uiFreeCount为空闲内存块的数量。


相关文章
|
2月前
|
算法 C++ 容器
C++标准库(速查)总结
C++标准库(速查)总结
79 6
|
2月前
|
存储 算法 C++
C++ STL 初探:打开标准模板库的大门
C++ STL 初探:打开标准模板库的大门
112 10
|
2月前
|
编译器 C++ 开发者
【C++】深入解析C/C++内存管理:new与delete的使用及原理(三)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
1月前
|
存储 缓存 C语言
【c++】动态内存管理
本文介绍了C++中动态内存管理的新方式——`new`和`delete`操作符,详细探讨了它们的使用方法及与C语言中`malloc`/`free`的区别。文章首先回顾了C语言中的动态内存管理,接着通过代码实例展示了`new`和`delete`的基本用法,包括对内置类型和自定义类型的动态内存分配与释放。此外,文章还深入解析了`operator new`和`operator delete`的底层实现,以及定位new表达式的应用,最后总结了`malloc`/`free`与`new`/`delete`的主要差异。
52 3
|
1月前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
88 4
|
2月前
|
存储 程序员 编译器
简述 C、C++程序编译的内存分配情况
在C和C++程序编译过程中,内存被划分为几个区域进行分配:代码区存储常量和执行指令;全局/静态变量区存放全局变量及静态变量;栈区管理函数参数、局部变量等;堆区则用于动态分配内存,由程序员控制释放,共同支撑着程序运行时的数据存储与处理需求。
154 21
|
2月前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
2月前
|
存储 程序员 C++
C++常用基础知识—STL库(2)
C++常用基础知识—STL库(2)
79 5
|
2月前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
|
2月前
|
存储 自然语言处理 程序员
C++常用基础知识—STL库(1)
C++常用基础知识—STL库(1)
72 1