导读:本期聚焦于小伙伴创作的《c++的std::pmr有什么用?Polymorphic Memory Resources如何实现运行时内存策略切换》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《c++的std::pmr有什么用?Polymorphic Memory Resources如何实现运行时内存策略切换》有用,将其分享出去将是对创作者最好的鼓励。

C++17引入的std::pmr(Polymorphic Memory Resources)是一套多态内存资源框架,核心目标是让内存分配策略可以在运行时动态切换,解决传统静态分配器无法适配多场景内存需求的问题。它把内存分配的逻辑和具体使用内存的业务代码解耦,开发者只需要替换底层的内存资源对象,就能改变整个模块的内存分配行为。

c++的std::pmr有什么用?Polymorphic Memory Resources如何实现运行时内存策略切换

std::pmr的核心价值

传统的C++内存分配依赖全局的new/delete或者模板化的静态分配器,分配策略在编译期就固定了,想要切换不同的分配逻辑往往需要修改大量代码。而std::pmr通过多态的设计,让内存资源成为可以运行时替换的对象,主要有以下几个核心用途:

  • 解耦内存分配逻辑和业务代码,业务代码不需要感知底层是用堆分配、内存池分配还是栈分配
  • 支持运行时动态切换分配策略,同一个容器在不同场景下可以使用不同的内存资源
  • 提供标准的内存资源实现,比如std::pmr::new_delete_resourcestd::pmr::null_memory_resourcestd::pmr::unsynchronized_pool_resource等,开箱即用
  • 方便实现自定义内存资源,适配特殊场景的内存分配需求,比如共享内存、预分配内存块等

std::pmr的核心组件

std::pmr的体系主要包含三个核心部分:

1. 内存资源基类std::pmr::memory_resource

这是一个抽象基类,定义了内存分配的核心接口,所有自定义内存资源都需要继承这个类并实现对应的虚函数:

#include <memory_resource>

// 自定义内存资源示例,继承std::pmr::memory_resource
class custom_memory_resource : public std::pmr::memory_resource {
private:
    // 实现分配内存的虚函数
    void* do_allocate(size_t bytes, size_t alignment) override {
        // 这里可以实现自定义分配逻辑,比如从预分配的内存池中分配
        return ::operator new(bytes);
    }

    // 实现释放内存的虚函数
    void do_deallocate(void* p, size_t bytes, size_t alignment) override {
        ::operator new(p);
    }

    // 实现相等判断的虚函数,判断两个内存资源是否等价
    bool do_is_equal(const memory_resource& other) const noexcept override {
        // 通常判断类型是否相同即可
        return typeid(other) == typeid(*this);
    }
};

2. 标准内存资源实现

C++标准已经提供了几个常用的内存资源实现,开发者可以直接使用:

内存资源类型作用说明
std::pmr::new_delete_resource使用全局的new和delete进行内存分配,是默认的内存资源
std::pmr::null_memory_resource分配内存时直接抛出异常,用于测试不允许内存分配的场景
std::pmr::synchronized_pool_resource线程安全的内存池资源,适合多线程场景下的频繁小内存分配
std::pmr::unsynchronized_pool_resource非线程安全的内存池资源,单线程场景下性能更高

3. 多态分配器std::pmr::polymorphic_allocator

这是一个分配器模板,作为容器和内存资源之间的桥梁,它内部持有一个std::pmr::memory_resource*指针,所有分配操作都委托给这个指针指向的内存资源。标准容器只要使用这个分配器,就能支持运行时切换内存资源。

运行时内存策略切换示例

下面通过一个完整的示例展示如何使用std::pmr实现运行时内存策略的切换:

#include <iostream>
#include <memory_resource>
#include <vector>
#include <string>

int main() {
    // 1. 使用默认的内存资源(new_delete_resource)创建pmr容器
    std::pmr::vector<int> vec1;
    vec1.push_back(1);
    vec1.push_back(2);
    std::cout << "使用默认内存资源,vec1大小: " << vec1.size() << std::endl;

    // 2. 准备一个内存池资源
    std::pmr::unsynchronized_pool_resource pool_res;

    // 3. 运行时切换到内存池资源,创建新的pmr容器
    std::pmr::vector<int> vec2{&pool_res};
    vec2.push_back(3);
    vec2.push_back(4);
    vec2.push_back(5);
    std::cout << "使用内存池资源,vec2大小: " << vec2.size() << std::endl;

    // 4. 自定义内存资源示例
    class log_memory_resource : public std::pmr::memory_resource {
    public:
        void* do_allocate(size_t bytes, size_t alignment) override {
            std::cout << "分配内存,大小: " << bytes << " 字节" << std::endl;
            return ::operator new(bytes);
        }

        void do_deallocate(void* p, size_t bytes, size_t alignment) override {
            std::cout << "释放内存,大小: " << bytes << " 字节" << std::endl;
            ::operator delete(p);
        }

        bool do_is_equal(const memory_resource& other) const noexcept override {
            return typeid(other) == typeid(*this);
        }
    };

    log_memory_resource log_res;
    // 运行时切换到自定义日志内存资源
    std::pmr::string str{&log_res};
    str = "hello std::pmr";
    std::cout << "自定义内存资源下的字符串: " << str << std::endl;

    return 0;
}

上面的示例中,vec1使用默认的内存资源,vec2在构造时传入了内存池资源的指针,就切换到了内存池分配策略,str则使用了自定义的带日志功能的内存资源,整个过程不需要修改容器的使用逻辑,只需要在构造时传入不同的内存资源指针即可,完美实现了运行时内存策略的切换。

使用注意事项

  • std::pmr是C++17引入的特性,使用时需要保证编译器支持C++17及以上标准
  • 内存资源的生命周期需要长于使用它的容器,避免容器还在使用内存资源时资源已经被释放
  • 多线程场景下如果使用非线程安全的内存资源,需要自己加锁保证线程安全,或者直接使用std::pmr::synchronized_pool_resource
  • 自定义内存资源时,需要正确实现三个虚函数,尤其是do_is_equal函数,否则可能导致容器之间的分配器比较出现问题
std::pmr的核心优势在于把内存分配策略的决策从编译期推迟到运行时,让内存管理更加灵活,尤其适合需要适配多种内存分配场景的库开发或者性能敏感的程序优化。

std::pmrPolymorphic_Memory_Resources内存分配器运行时内存策略c++修改时间:2026-07-13 12:06:33

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。