073. 编写代码实现简单的内存池
内存池(Memory Pool)是一种高效的内存管理技术,用于预先分配一块较大的内存区域,并从中分配和回收小块内存。内存池可以显著减少动态内存分配的开销,提高程序的性能,尤其是在频繁分配和释放小块内存的场景中。
1. 内存池的实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义内存池结构
typedef struct MemoryPool {
char* pool; // 内存池的起始地址
size_t poolSize; // 内存池的总大小
size_t blockSize; // 每个内存块的大小
int numBlocks; // 内存池中的块数
int* freeList; // 空闲块的链表
int freeCount; // 空闲块的数量
} MemoryPool;
// 初始化内存池
void initMemoryPool(MemoryPool* pool, size_t poolSize, size_t blockSize) {
pool->pool = (char*)malloc(poolSize);
if (pool->pool == NULL) {
printf("内存分配失败!\n");
exit(1);
}
pool->poolSize = poolSize;
pool->blockSize = blockSize;
pool->numBlocks = poolSize / blockSize;
pool->freeList = (int*)malloc(pool->numBlocks * sizeof(int));
if (pool->freeList == NULL) {
printf("内存分配失败!\n");
exit(1);
}
for (int i = 0; i < pool->numBlocks; i++) {
pool->freeList[i] = i;
}
pool->freeCount = pool->numBlocks;
}
// 从内存池中分配内存
void* allocateFromPool(MemoryPool* pool) {
if (pool->freeCount == 0) {
printf("内存池已满,无法分配更多内存!\n");
return NULL;
}
int index = pool->freeList[--pool->freeCount];
return pool->pool + index * pool->blockSize;
}
// 将内存返回到内存池
void freeToPool(MemoryPool* pool, void* ptr) {
int index = (char*)ptr - pool->pool;
if (index < 0 || index >= pool->poolSize || (index % pool->blockSize != 0)) {
printf("无效的指针!\n");
return;
}
index /= pool->blockSize;
pool->freeList[pool->freeCount++] = index;
}
// 销毁内存池
void destroyMemoryPool(MemoryPool* pool) {
free(pool->pool);
free(pool->freeList);
pool->pool = NULL;
pool->poolSize = 0;
pool->blockSize = 0;
pool->numBlocks = 0;
pool->freeList = NULL;
pool->freeCount = 0;
}
int main() {
MemoryPool pool;
initMemoryPool(&pool, 1024, 64); // 初始化内存池,总大小1024字节,每个块64字节
void* block1 = allocateFromPool(&pool);
void* block2 = allocateFromPool(&pool);
printf("分配的内存块1: %p\n", block1);
printf("分配的内存块2: %p\n", block2);
freeToPool(&pool, block1);
printf("释放内存块1\n");
void* block3 = allocateFromPool(&pool);
printf("重新分配的内存块1: %p\n", block3);
destroyMemoryPool(&pool); // 销毁内存池
return 0;
}
2. 代码说明
内存池结构:
-
pool
:内存池的起始地址。 -
poolSize
:内存池的总大小。 -
blockSize
:每个内存块的大小。 -
numBlocks
:内存池中的块数。 -
freeList
:空闲块的链表。 -
freeCount
:空闲块的数量。
初始化内存池:
-
分配内存池的总内存。
-
初始化空闲块链表,将所有块标记为可用。
分配内存:
-
从空闲块链表中取出一个块。
-
返回该块的地址。
释放内存:
- 将释放的块的索引添加到空闲块链表中。
销毁内存池:
- 释放内存池的总内存和空闲块链表。
3. 示例运行
输入:
无输入
输出:
分配的内存块1: 0x12345678
分配的内存块2: 0x123456b8
释放内存块1
重新分配的内存块1: 0x12345678
4. 注意事项
- 内存对齐:确保内存块的大小满足对齐要求,以提高访问效率。
- 内存池大小:内存池的总大小和块大小应根据实际需求进行调整。
- 线程安全:在多线程环境中,需要对内存池的操作进行同步,以避免竞态条件。
- 错误处理:在分配和释放内存时,应进行错误检查,确保操作的合法性。
5. 总结
内存池是一种高效的内存管理技术,适用于频繁分配和释放小块内存的场景。通过实现一个简单的内存池,可以显著减少动态内存分配的开销,提高程序的性能。在实际应用中,可以根据具体需求对内存池进行优化和扩展。
视频讲解
BiliBili: 视睿网络-哔哩哔哩视频 (bilibili.com)