Skip to content

C++ PMR:资源协议、传播与生命周期 ​

资源协议与上游分配 ​

先理解 RAII、容器与分配/释放配对。本节沿slab_resource.hpp 的资源适配器解释 PMR 协议和上游路由,示例未执行。

专题入口:C++ PMR:资源协议与上游分配 · C++ PMR:传播、等价与资源生存期 · C++ PMR完整实践:复用 C 定长池 · C++ PMR排错:悬空资源、错误归还与误测

C++PMR工程采用什么语言标准 ​

C++PMR工程采用什么语言标准:采用 C++20 和 C11,不依赖第三方库。PMR自C++17进入标准库,本工程选择C++20作为教学标准,并非使用最新工作草案的所有新增接口。资源是运行时策略对象;std::pmr容器类型不因资源实例不同而改变,适合在同一调用接口选择分配策略。

C++memory_resource的三个操作是什么 ​

C++memory_resource的三个操作是什么:派生类实现 do_allocate、do_deallocate 和do_is_equal,公共接口负责转发。allocate必须给出满足大小及对齐的存储或抛出适当异常;deallocate必须收到原指针及匹配bytes/alignment,存储此前未归还,资源等价。资源管理存储,容器负责构造析构元素;把C返回地址直接看作已构造复杂对象是错误的。

C++池空时如何正确转交upstream ​

C++池空时如何正确转交upstream:支持的小请求也可能因池空走upstream,超大或扩展对齐请求同样转发。释放时必须依据归属选择路径,不能只根据bytes/alignment重算分配决策。这里检查是否精确池块起点,其余按合法PMR契约转给原上游;不为任意无效指针兜底。调用者必须确保上游活得比资源久。

C++monotonic和pool资源怎样选择 ​

C++monotonic和pool资源怎样选择:阶段性批量数据适合monotonic_buffer_resource,单个deallocate不回收,阶段结束release整体释放;容器先销毁,不能在仍持有元素时release。频繁申请归还多种小尺寸可考虑unsynchronized_pool_resource,单线程使用并可能保留空闲块至release或销毁。自制固定池可限制尺寸与预分配量,但要承担契约证明及观测成本,不能默认更快。

独立练习 ​

256字节池空后申请16字节,归还时能否依据16<=256把它放回池?

参考答案(先独立推演)

不能;该请求可能来自upstream,必须依据归属归还同一资源。样例用块起点匹配,在合法调用契约下区分来源。

一手资料与边界 ​

2026-10-17核对 WG14 C11 N1570 6.2.8、6.5.6、6.5.8与7.22.3;C++资源协议工作草案用于溯源,滚动草案的新接口不自动纳入C++20;Allocator要求用于核对传播边界。国内资料核读 Microsoft中文memory_resource概览,平台实现说明不推广为所有标准库。项目未编译、未执行,普通静态模板通过不能证明内存安全。

传播、等价与资源生存期 ​

先读前节资源协议,再比较容器复制、移动与 swap 对资源身份的要求。资源类和测试见完整项目源码,示例未执行。

专题入口:C++ PMR:资源协议与上游分配 · C++ PMR:传播、等价与资源生存期 · C++ PMR完整实践:复用 C 定长池 · C++ PMR排错:悬空资源、错误归还与误测

C++PMR资源和容器谁必须先销毁 ​

C++PMR资源和容器谁必须先销毁:容器必须先销毁,再销毁资源,最后才释放资源借用的上游。局部变量按构造逆序销毁,因此先声明资源再声明容器;把容器从函数返回却让局部资源结束会留下悬空allocator。shared_ptr管理资源时也要保证容器持有相应拥有关系,单独保存memory_resource裸指针没有延长生存期。

C++PMR资源相等到底意味着什么 ​

C++PMR资源相等到底意味着什么:相等表示两个资源间可以双向释放彼此分配的存储,而不是尺寸、配置或上游相同。本实现只在this地址相同返回true,因为不同实例有独立位图和空闲链;即使它们上游相同也不可以互还池槽。错误声明相等会允许容器转移存储,最终破坏归还路径。

C++PMR复制容器会沿用原资源吗 ​

C++PMR复制容器会沿用原资源吗:普通容器复制构造通过select_on_container_copy_construction选择默认资源,不应假定沿用源实例;要确定选择就用带allocator的显式复制构造。默认资源可能被进程其他代码改变,测试应比较resource指针或显式提供目标,不能从输出值相同推断分配位置相同。

C++PMR移动赋值和swap如何传播资源 ​

C++PMR移动赋值和swap如何传播资源:polymorphic_allocator在复制赋值、移动赋值和swap时不传播。移动赋值遇到不等资源可能逐元素移动并在目标资源分配,不能假设只交换指针;无allocator参数的移动构造与此不同。资源不等时直接swap标准容器违反分配器前提,先检查等价,或显式构造目标资源的新容器;泛型强保证不能无条件依赖swap。

独立练习 ​

两个池块宽和上游都相同,能否交换其PMR容器?

参考答案(先独立推演)

两个资源仍不等价,不能直接swap;用带目标allocator的复制或逐元素迁移,并重新考虑异常与峰值内存。

一手资料与边界 ​

2026-10-17核对 WG14 C11 N1570 6.2.8、6.5.6、6.5.8与7.22.3;C++资源协议工作草案用于溯源,滚动草案的新接口不自动纳入C++20;Allocator要求用于核对传播边界。国内资料核读 Microsoft中文memory_resource概览,平台实现说明不推广为所有标准库。项目未编译、未执行,普通静态模板通过不能证明内存安全。

悬空资源、错误归还与误测 ​

先画出容器、资源和上游的拥有顺序,再对照资源实现及 test_resource.cpp定位悬空或错误归还;本节不提供性能实测数据。

专题入口:C++ PMR:资源协议与上游分配 · C++ PMR:传播、等价与资源生存期 · C++ PMR完整实践:复用 C 定长池 · C++ PMR排错:悬空资源、错误归还与误测

C++PMR容器离开函数后为什么崩溃 ​

C++PMR容器离开函数后为什么崩溃:先查返回容器是否绑定函数内的局部资源,资源结束后allocator裸指针悬空,下一次扩容或析构都会访问失效对象。修复要让拥有者把资源与容器一起管理,并保证逆序销毁;复制容器时显式选择长寿命目标资源也是一种边界方案。只给容器加shared_ptr不能自动延长资源寿命。

C++PMR归还时bytes不一致会怎样 ​

C++PMR归还时bytes不一致会怎样:deallocate的前提要求原始bytes与alignment一致,即使本池当前没用这两个值也不能随便传0或sizeof指针。上游可能按尺寸选择释放路径,错误大小是调用契约违例。记录原请求元组和资源身份定位问题;不要靠捕获异常修复,因为deallocate不能抛异常,违例也没有可恢复保证。

C++PMR析构触发terminate怎样定位 ​

C++PMR析构触发terminate怎样定位:本教学资源在析构时发现live非零就terminate,先查看尚未销毁的容器、直接allocate的未归还块和资源借用关系。这个检查只在资源对象仍合法时有意义,不能保证发现所有悬空访问。析构发生时再试图释放未知类型元素不安全,必须修正上层拥有顺序。

C++定长池性能怎样避免误测 ​

C++定长池性能怎样避免误测:先记录节点尺寸、分配次数、池命中率、峰值存活及上游字节,再在相同输入、优化配置和生命周期下比较端到端成本。池查归属的线性扫描、缓存局部性、预分配时间都可能影响结果;把初始化排除时必须同时报告原因。当前只有预期和测试源码,没有基准数据,不声称比标准资源更快。

独立练习 ​

若live归零且demo打印21,能否认定不存在悬空指针或性能改善?

参考答案(先独立推演)

不能。计数与校验和只覆盖本次逻辑,旧别名、跨线程误用和未走到的异常路径仍可能存在;性能需单独测量并报告比较边界。

一手资料与边界 ​

2026-10-17核对 WG14 C11 N1570 6.2.8、6.5.6、6.5.8与7.22.3;C++资源协议工作草案用于溯源,滚动草案的新接口不自动纳入C++20;Allocator要求用于核对传播边界。国内资料核读 Microsoft中文memory_resource概览,平台实现说明不推广为所有标准库。项目未编译、未执行,普通静态模板通过不能证明内存安全。

继续阅读