内存管理一直是一件令人头疼的事,针对内存管理,Boost 提供了一套从底层对齐控制、内存池、智能指针到跨进程共享内存的完整工具链。下面按场景分类介绍。
一. 智能指针(Smart Pointers)
尽管 C++11 引入了 std::shared_ptr, std::weak_ptr, std::unique_ptr,但 Boost 仍有其独有价值,尤其是侵入式指针和本地共享指针。
| Smart Ptr | <boost/smart_ptr.hpp> | shared_ptr, weak_ptr | C++11 前的事实标准,现推荐使用标准库版本 |
| scoped_ptr | 类似 unique_ptr 但不可移动,已不建议使用 | ||
| intrusive_ptr | 侵入式引用计数,对象自己维护计数,更轻量 | ||
| local_shared_ptr | 结合本地存储和共享所有权的指针,避免 shared_ptr 的线程安全开销 | ||
| make_shared / allocate_shared | 与标准一致 |
scoped_ptr
scoped_ptr 是 Boost 智能指针库中的一个老组件,用于独占资源所有权,并在指针离开作用域时自动 delete 释放对象。
基本特征
-
独占所有权:一个对象同一时间只能被一个 scoped_ptr 管理。
-
不可拷贝、不可转移:拷贝构造和赋值操作都是私有的,无法传递所有权。对象严格限定在声明它的作用域内。
-
轻量级:没有引用计数,没有控制块,比 shared_ptr 更轻。
-
异常安全:确保资源在异常发生时也能被正确释放。
intrusive_ptr
boost::intrusive_ptr 是 Boost 智能指针家族中最轻量、最高效的引用计数智能指针。它与 boost::shared_ptr 或 std::shared_ptr 最大的区别是:引用计数器存储在对象内部,而不是分配在独立的控制块上。
为什么叫“侵入式” (Intrusive)?因为对象本身必须提供两个函数接口来维护引用计数:
-
intrusive_ptr_add_ref(T*) —— 增加引用计数
-
intrusive_ptr_release(T*) —— 减少引用计数,当计数归零时负责销毁对象
这两个函数由你定义(通常在对象所在命名空间或作为友元),Boost 会在构造/拷贝/析构 intrusive_ptr 时自动调用它们。
2. 和 shared_ptr 的核心区别
| 引用计数位置 | 堆上独立控制块(每次构造 shared_ptr 都会分配) | 对象内部(通常是一个整型成员) |
| 内存开销 | 两次分配:一次对象,一次控制块 | 仅分配对象本身(计数内嵌) |
| 性能 | 控制块分配、原子操作(线程安全) | 零额外分配;是否原子操作由你决定(可非线程安全) |
| 构造方式 | shared_ptr<T> p(new T); 或 make_shared | intrusive_ptr<T> p(new T); 但对象必须已实现计数接口 |
| 对象类型要求 | 任意类型 | 对象必须支持侵入式引用计数(即拥有 add_ref / release 机制) |
| 与裸指针互操作 | 不能直接从已有裸指针安全创建另一个 shared_ptr | 可从已有裸指针安全构造多个 intrusive_ptr(因为计数在对象内) |
| 适用场景 | 通用引用计数,简单易用 | 与现有引用计数系统(如 COM、内部框架)无缝集成;极致性能要求 |
#include <boost/smart_ptr/intrusive_ptr.hpp>
//定义侵入式计数函数
class MyObject {
private:
unsigned int ref_count_ = 0; // 引用计数
public:
// 允许 intrusive_ptr 操作计数
friend void intrusive_ptr_add_ref(MyObject* p) {
++p->ref_count_;
}
friend void intrusive_ptr_release(MyObject* p) {
if (–p->ref_count_ == 0)
delete p;
}
virtual ~MyObject() = default; // 注意:最好为多态基类,否则 delete 需要正确调用析构
void do_something() { /* … */ }
};
//直接使用 intrusive_ptr
boost::intrusive_ptr<MyObject> p1(new MyObject); // ref_count_ 变为 1
boost::intrusive_ptr<MyObject> p2 = p1; // ref_count_ 变为 2
p1.reset(); // ref_count_ 减为 1
// 当 p2 离开作用域,ref_count_ 归零,自动 delete
二. 内存池(Boost.Pool)
Boost.Pool 是专门设计用于快速分配大量固定大小的小对象的库,可有效减少内存碎片和 malloc 调用开销。
| <boost/pool/pool.hpp> | boost::pool | 最基本的无类型内存池,一次分配固定大小的内存块 |
| <boost/pool/object_pool.hpp> | boost::object_pool<T> | 类型安全的对象池,自动调用构造/析构 |
| <boost/pool/singleton_pool.hpp> | boost::singleton_pool | 带单例优化的线程安全内存池 |
| <boost/pool/pool_alloc.hpp> | pool_allocator | 可作为 STL 容器(如 std::list)的分配器 |
#include <boost/pool/object_pool.hpp>
struct Point { int x, y; };
boost::object_pool<Point> pool;
Point* p1 = pool.construct(); // 分配并构造(如无参,则使用默认构造)
p1->x = 10; p1->y = 20;
Point* p2 = pool.malloc(); // 仅分配内存,不构造
new (p2) Point{30, 40}; // placement new
pool.destroy(p1); // 调用析构并释放回池
pool.free(p2); // 仅释放内存(不调用析构)
// pool 析构时会自动释放所有未还回的内存(但不会调用析构,注意泄漏)
注意:object_pool::destroy() 会调用析构函数并释放内存;而 free() 不调用析构。如果对象生命周期管理不当,会造成资源泄漏。
编译依赖:Boost.Pool 需要编译和链接(-lboost_pool)。
三. 内存对齐(Boost.Align)
C++11 有 alignas,但 Boost.Align 提供更灵活的运行时对齐分配函数和分配器。
| <boost/align/aligned_alloc.hpp> | aligned_alloc(alignment, size) 运行时对齐分配 |
| <boost/align/aligned_delete.hpp> | aligned_delete 专门用于对齐内存的删除器 |
| <boost/align/aligned_allocator.hpp> | aligned_allocator<T, Alignment> 可作为容器分配器 |
示例:
#include <boost/align/aligned_alloc.hpp>
#include <boost/align/aligned_allocator.hpp>
#include <vector>
// 分配 16 字节对齐的内存
void* p = boost::alignment::aligned_alloc(16, 1024);
boost::alignment::aligned_free(p); // 必须用对应的释放
// 用于 std::vector,所有元素 16 字节对齐
std::vector<int, boost::alignment::aligned_allocator<int, 16>> v;
四. 容器分配器与作用域分配器(Boost.Container)
Boost.Container 不仅提供了更丰富的容器(如 flat_map, stable_vector),还提供了分配器工具,用于复杂的嵌套容器内存管理。
-
<boost/container/scoped_allocator.hpp> 实现 scoped_allocator_adaptor,允许容器的元素(本身也是容器)使用同一个分配器。
-
适合在共享内存等场景下,所有子对象都从同一内存区域分配。
#include <boost/container/scoped_allocator.hpp>
#include <boost/container/list.hpp>
#include <boost/container/vector.hpp>
#include <boost/pool/pool_alloc.hpp>
using Alloc = boost::pool_allocator<int>;
using MyList = boost::container::list<int, Alloc>;
using MyVec = boost::container::vector<MyList, boost::container::scoped_allocator_adaptor<Alloc>>;
Alloc alloc;
MyVec vec(alloc); // 向量及其内部的链表都使用同一个 pool_allocator
vec.emplace_back(); // 内部 list 自动继承分配器
五. 共享内存(Boost.Interprocess)
如果“内存管理”指的是跨进程共享内存,则需要 Boost.Interprocess。它提供:
-
shared_memory_object / mapped_region 创建/映射共享内存
-
managed_shared_memory 可在共享内存上直接构造对象
-
特殊分配器(allocator),让 STL 容器放在共享内存里
-
同步原语(互斥锁、条件变量)用于进程间同步
六. 其他相关
-
Boost.Smart_Ptr 的 make_unique 等在 C++11 后基本被标准取代,但维护旧代码时会碰到。
-
Boost.Any、Boost.Variant 内部也涉及动态内存分配,但不属于专门的内存管理库。
-
Boost.Circular_Buffer 使用连续内存,可避免频繁分配。
如何选择?
| 大量小对象频繁分配/释放 | boost::object_pool |
| 需要对齐分配(SIMD、DMA) | boost::alignment::aligned_alloc |
| 侵入式引用计数,避免多控块开销 | boost::intrusive_ptr |
| STL 容器定制内存来源(如共享内存) | pool_allocator 或自定义分配器 |
| 多进程通信与内存共享 | Boost.Interprocess |



