polymorphic_allocator 是 pmr 的使用者封装,不实现内存管理逻辑,仅转发调用 std::memory_resource 派生类的 do_allocate/do_deallocate;真正决定内存分配行为的是所绑定的 resource。

polymorphic_allocator 是什么,不是什么
polymorphic_allocator 本身不实现 PMR(Polymorphic Memory Resource),它只是 PMR 的**使用者封装**。真正负责内存分配/释放逻辑的是 std::memory_resource 派生类(比如 std::pmr::pool_resource 或自定义资源)。polymorphic_allocator 只是把传入的 std::memory_resource* 存起来,并在 allocate()/deallocate() 时转发调用其 do_allocate()/do_deallocate()。
怎么让 vector 真正用上自定义 memory_resource
关键不是换 allocator 类型,而是确保所有嵌套容器都使用同一资源——std::pmr::string 和 std::pmr::vector 是必须的,普通 std::string 会无视你传的 polymorphic_allocator。
- 用
std::pmr::vector<:pmr::string></:pmr::string>,而不是std::vector<:string></:string> - 构造时显式传入
polymorphic_allocator,或通过std::pmr::vector的默认构造(依赖当前线程默认资源) - 若用
std::pmr::vector<t></t>,T 的内部存储(如std::pmr::string的字符缓冲区)才会走该 resource;T 是std::string则仍走全局 new
示例:
std::pmr::monotonic_buffer_resource pool{1024};
std::pmr::polymorphic_allocator<char> alloc{&pool};
std::pmr::vector<:pmr::string> vec{alloc}; // ✅ 全链路受控
vec.emplace_back("hello"); // 字符串数据也分配在 pool 中
</:pmr::string></char>
为什么 swap 后内存没释放,甚至 crash
polymorphic_allocator 的相等性(==)只比较所持 memory_resource* 指针是否相同。两个 allocator 若指向不同 resource,即使内容一致,也不可交换容器——std::vector::swap() 要求 allocator 相等,否则行为未定义(常见于 MSVC debug 模式直接 abort)。
- 不要跨 resource 创建容器再 swap:比如一个用
pool_resource,另一个用new_delete_resource() - 避免隐式拷贝构造 allocator:某些 STL 实现中,容器拷贝可能生成新 allocator 实例,但 resource 指针丢失(尤其在模板推导时)
- 调试时检查
alloc1 == alloc2返回值,别假设“都是 pmr 就能混用”
自定义 memory_resource 容易漏掉的关键点
继承 std::memory_resource 时,仅重写 do_allocate/do_deallocate/do_is_equal 不够。漏掉以下任一,PMR 行为就不可靠:
-
do_is_equal必须正确实现:返回this == other是常见错误;应判断语义等价(比如两个pool_resource是否共享同一内存池) - 若支持对齐(非 1-byte 对齐),
do_allocate(size, align)中 align 参数必须被实际使用,否则aligned_alloc或_aligned_malloc可能失败 - 析构时,resource 若管理外部内存(如 mmap 区域),需确保
do_deallocate能安全处理重复调用或空指针
最简可靠实现:先用 std::pmr::synchronized_pool_resource 验证逻辑,再替换为自定义 resource。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











