0

0

C++内存池实现 自定义分配器开发指南

P粉602998670

P粉602998670

发布时间:2025-08-29 12:06:01

|

906人浏览过

|

来源于php中文网

原创

答案:文章介绍C++内存池与自定义分配器的实现,通过预分配内存块管理小对象分配,提升性能。核心为MemoryPool类实现O(1)分配释放,减少碎片;PoolAllocator模板使STL容器兼容内存池,示例展示其在std::vector中的应用,强调对齐、静态池管理及适用场景。

c++内存池实现 自定义分配器开发指南

在C++中,频繁调用

new
delete
malloc
free
进行小对象分配会带来显著的性能开销,主要源于系统调用、内存碎片以及对齐处理。为解决这一问题,内存池(Memory Pool)结合自定义分配器(Custom Allocator)是一种高效方案。本文将带你从零实现一个简单的C++内存池,并开发配套的STL兼容分配器。

内存池基本原理

内存池预先分配一大块连续内存,按固定大小切分为多个槽(slot),每次分配只需返回一个空闲槽,释放时将其重新标记为空闲。这种方式避免了操作系统频繁介入,极大提升小对象分配效率。

核心特点:

  • 固定块大小,适合频繁分配/释放同类对象
  • 分配与释放时间复杂度为 O(1)
  • 减少内存碎片,提升缓存局部性

简易内存池实现

以下是一个支持固定大小对象的内存池类:

立即学习C++免费学习笔记(深入)”;

Pi智能演示文档
Pi智能演示文档

领先的AI PPT生成工具

下载
// MemoryPool.h

class MemoryPool {
private:
    struct Block {
        Block* next;
    };

    Block* freeList;
    char* memory;
    size_t blockSize;
    size_t poolSize;

public:
    MemoryPool(size_t count, size_t size)
        : blockSize((size + alignof(Block) - 1) / alignof(Block) * alignof(Block)),
         poolSize(count), freeList(nullptr) {
        memory = new char[blockSize * count];
        initializePool();
    }

    ~MemoryPool() {
        delete[] memory;
    }

    void* allocate() {
        if (!freeList) return nullptr;
        Block* block = freeList;
        freeList = freeList->next;
        return block;
    }

    void deallocate(void* p) {
        Block* block = static_cast(p);
        block->next = freeList;
        freeList = block;
    }

private:
    void initializePool() {
        for (size_t i = 0; i             Block* block = reinterpret_cast(memory + i * blockSize);
            block->next = freeList;
            freeList = block;
        }
    }
};

STL兼容的自定义分配器

要让STL容器(如

std::vector
std::list
)使用内存池,需实现符合Allocator要求的模板类。

// PoolAllocator.h

template
class PoolAllocator {
public:
    using value_type = T;
    using pointer = T*;
    using const_pointer = const T*;
    using reference = T&;
    using const_reference = const T&;
    using size_type = std::size_t;
    using difference_type = std::ptrdiff_t;

    template
    struct rebind {
        using other = PoolAllocator;
    };

    PoolAllocator() {
        if (!pool) {
            pool = new MemoryPool(N, sizeof(T));
        }
    }

    ~PoolAllocator() = default;

    template
    PoolAllocator(const PoolAllocator&) {}

    pointer allocate(size_type n) {
        if (n == 1) {
            return static_cast(pool->allocate());
        }
        throw std::bad_alloc();
    }

    void deallocate(pointer p, size_type n) {
        if (n == 1) {
            pool->deallocate(p);
        }
    }

    template
    void construct(U* p, Args&&... args) {
        new(p) U(std::forward(args)...);
    }

    void destroy(pointer p) {
        p->~T();
    }

    static MemoryPool* pool;
};

template
MemoryPool* PoolAllocator::pool = nullptr;

使用示例

将自定义分配器用于

std::vector

#include
struct Point {
    float x, y;
    Point(float x = 0, float y = 0) : x(x), y(y) {}
};

int main() {
    using PoolVec = std::vector>;
    PoolVec points;
    points.emplace_back(1.0f, 2.0f);
    points.emplace_back(3.0f, 4.0f);
    // 所有Point对象由内存池分配
    return 0;
}

注意:此分配器仅支持单对象分配(n=1),不适用于需要连续大块内存的场景。

基本上就这些。通过内存池+自定义分配器,你可以显著优化特定场景下的内存性能。关键是理解分配模式,合理设计块大小和池容量。不复杂但容易忽略细节,比如对齐和静态池管理。实际项目中可考虑使用

boost::pool
或进一步支持多尺寸池。

相关专题

更多
css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

553

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

95

2025.10.23

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

713

2023.08.22

counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

193

2023.11.20

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

519

2023.09.20

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

312

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

522

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

48

2025.08.29

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
php-src源码分析探索
php-src源码分析探索

共6课时 | 0.5万人学习

c语言项目php解释器源码分析探索
c语言项目php解释器源码分析探索

共7课时 | 0.3万人学习

swoole进程树解析
swoole进程树解析

共4课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号