【c++】——内存池

本文介绍了内存池的概念和重要性,详细讲解了如何利用静态链表管理方式实现一个简单的链队内存池,包括内存池的管理优化、链队列结点类的设计以及链队列的链表结构。此外,还探讨了如何进一步实现一个通用内存池,以适应不同类别的内存管理需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、引言

1.1自主内存管理机制来源

在我们实际的使用过程中如果出现了频繁new和delete,会出现以下问题:

  1. 效率不高
  2. 外碎片问题

【补充】——内碎片和外碎片
外碎片:内存分配后,释放后该内存没有办法被重新释放。
内碎片:由于内存对齐而浪费的一些内存,比如下面的这个结构体,其中就浪费了三个字节的内存

struct Data
{
   int al;
   char b1;
};

所以我们要针对这两点的不足,自己实现一个内存管理机制。

1.2静态链表的管理方式

1、原理
数组的形式存在,做链表的处理

2、操作过程

1、开辟空间
首先,将整个内存划分成一个一个数组,接下来把数组划分成一个一个的结点,如下图所示:
在这里插入图片描述
2、初始化

  • 牺牲0号下标的空间,做未分配出去的链表的头结点
  • 牺牲最后一个下标的空间做已分配出去的链表的头结点

在这里插入图片描述

3、插入数据
未分配链表获取一个结点插入到已分配链表中。
【举个栗子】
比如说此时插入数字-1。就把1号下标的数据域置为1,然后让0号下标的游标域指向2号,5号下标的游标域指向1号。最后将1号下标的游标域置为-1,如图所示:
在这里插入图片描述
再插入1的时候就从未使用部分的第一个结点开始重复上面的操作。但是是让2号的游标域来标记2,如下图所示:
在这里插入图片描述
4、删除元素
已分配链表中删除一个结点插入到未分配链表中
【举个栗子】将1号下标元素的内存释放,就要将其在已使用部分移除,添加到未使用部分。
在这里插入图片描述

2、实现一个简单的链队内存池

2.1内存池的管理方式

1、优化
有了上面关于静态链表的管理方式的理解,内存池的管理方式在其基础上做了优化,优化如下:

  • 组织成不带头结点的单链表
  • 不需要对已分配的结点,通过一个链表做统一管理。因为这里面的内存块是针对外部的一个变量进行管理的,所以说这个内存在外部有标识单元来标识的,所以就不用考虑以分配结点,也就是谁new就谁来用。

2、结构的处理
1、初始化
分为两个区域,一个是数据域,一个是指针,用pool指针统一指向在这里插入图片描述
2、在外部new了一个内存
首先看有没有内存供外部使用,如果有的话,就在整个内存池里面删除一个结点供外部使用,然后pool指针指向下一个未被使用的结点。指针域只做链表的管理,不做数据域来使用的。
在这里插入图片描述
3、外部delete
这时就需要归还给内存池,只需要把该结点再插入到内存池就可以了
【举个栗子】

int* p = new int
* p = 20;
int* q = new int;
*q = 30;
delete q;

就是q所指向的位置指向poll当前所指向的位置。然后再让poll指向q所在的位置。具体如下图所示:

在这里插入图片描述
在这里插入图片描述

2.2链队列的结点类

结点的大体框架如下:

const int Node_count = 10;
template<typename T>
class Node
{
public:
	Node(T val=T())
		:mdata(val),pnext(NULL)
	{}
	void* operator new(size_t size);
	void operator delete(void* ptr);
private:
	template<typename T>
	friend class Queue;
	T mdata;
	Node<T>* pnext;
	static Node<T>* pool;
};

其中,包含数据域和指针域两个部分。因为在申请的时候是频繁的new队列里面的结点。所以在结点里面实现new、delete运算符的重载函数。

1、生成内存池的结构
就如上述框架里面的static Node<T>* pool;静态的成员变量在所有类中是共享的,以此来实现一个pool,并在类外初始化.

2、new运算符重载函数

  • 开辟空间:当pool为空的时候就需要开辟出内存块。其中size代表结点的大小。每次开辟const int Node_count个结点出来
  • 做初始化:通过指针加偏移的方式指向下一个结点。让各个结点的指针域都指向下一个结点的位置。
  • 开辟内存将第一个位置头删来实现供外部使用,给出一个标识表示开始位置,然后让pool移动
void* operator new(size_t size)
	{
   
		if 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值