news 2026/6/10 13:29:23

2601C++,pmr管理内存

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
2601C++,pmr管理内存

在现代C++编程中,高效且灵活的管理内存一直是追求的重要目标之一.
C++17标准中,引入了std::pmr::memory_resourcestd::polymorphic_allocator这两个强大的组件,它们为分配内存提供了高度的灵活性可扩展性,使你可根据不同应用场景和需求,更加精细地控制内存的分配和释放过程.
以下是对这两个组件的详细解析.

一,std::pmr::memory_resource

(一)基本概念

std::pmr::memory_resource是一个定义了一套标准的分配内存接口的抽象基类.
该接口为用户统一处理不同分配内存策略,允许用户根据具体需求自定义``分配内存,如线本分配内存,内存池分配等.

用该抽象基类,可统一管理和使用不同分配内存器,提高了代码的可维护性可扩展性.

(二)主要成员函数

1.allocate(std::size_tbytes)

功能:该函数用来分配指定字节数的内存.在实际应用中,它会根据具体的分配内存策略来找合适的内存块,并把它分配给调用者.

参数:字节参数表示要分配的字节数.该参数是调用者根据自身需求传入的,它决定了要分配的内存大小.
返回值:函数返回分配的内存的指针.调用者可用该指针来访问和操作分配的内存.

2.deallocate(void*ptr,std::size_tbytes)

功能:此函数用来释放指定指针指向的内存.当调用者不再使用之前分配的内存时,就可调用该函数释放该内存,这样其他程序可使用它.

参数:是要释放的内存的指针,指向之前分配函数分配的内存块开始位置.字节是该内存块的大小,用来帮助分配内存器``正确释放内存.

注意:在调用回收函数时,需要确保传入的指针和大小与之前分配函数返回的指针分配的大小一致,否则可能会泄漏内存或有其他未定义行为.

3.is_equal(const memory_resource&other)const noexcept

功能:该函数用来判断当前内存资源是否与另一个内存资源相等.这里的相等一般表示两个内存资源互相替代使用,即它们的分配和释放内存行为是兼容的.

参数:其他是与当前内存资源比较的另一个内存资源对象.
返回值:如果两个内存资源相等,则返回,否则返回.该函数有时非常有用,如在需要判断两个不同容器是否使用相同内存资源时.

(三)使用场景

1.分配内存灵活性

在不同应用场景中,可能需要不同分配内存策略.如,在多线程环境中,为了避免线程间的竞争和提高性能,可用线本分配内存策略.
std::pmr::memory_resource允许用户根据这些不同需求自定义分配内存策略,从而提高程序的性能和效率.

2.管理资源的统一性

大型项目中,可用多种不同分配内存器,会导致不同分配器间的冲突和管理困难.std::pmr::memory_resource提供的统一接口,可统一管理这些不同分配器,避免冲突,提高代码的可维护性.

二,std::polymorphic_allocator

(一)基本概念

std::polymorphic_allocator是一个多态分配器,它允许用户指定不同std::pmr::memory_resource对象来分配内存.

它是一个T模板参数表示分配器分配的元素类型的模板类.即std::polymorphic_allocator可按需分配不同类型的元素,且可用不同内存资源来分配.

(二)主要成员函数

1.allocate(std::size_tn)

功能:该函数用来分配n个元素的内存.它会调用关联的std::pmr::memory_resource对象的分配函数来实际分配内存.
参数:n表示要分配的元素数量.该参数决定了会根据T元素类型的大小计算的要分配的内存大小.
返回值:返回指向分配的第一个元素的位置分配的内存的指针.

2.deallocate(T*ptr,std::size_tn)

功能:此函数用来释放指定指针指向的内存.它会调用关联的std::pmr::memory_resource对象的回收函数来实际释放内存.

参数:是指向之前分配函数分配的内存块开始位置要释放的内存的指针.n是该内存块中用来帮助内存资源正确释放内存的元素数.

3.resource()

功能:该函数来取当前分配器使用的std::pmr::memory_resource对象.用它用户可了解当前分配器所使用的内存资源,且可在需要时切换或管理.
返回值:返回当前分配器使用的内存资源对象的指针.

(三)使用示例

#include<memory_resource>#include<iostream>#include<vector>intmain(){//创建`默认内存资源`std::pmr::memory_resource*default_resource=std::pmr::get_default_resource();//创建使用默认资源的`多态分配器`std::pmr::polymorphic_allocator<int>alloc(default_resource);//使用多态分配器`分配内存`std::pmr::vector<int,std::pmr::polymorphic_allocator<int>>vec(alloc);//添加元素vec.push_back(1);vec.push_back(2);vec.push_back(3);//`输出`元素for(inti:vec){std::cout<<i<<" ";}std::cout<<std::endl;return0;}

这里,首先用std::pmr::get_default_resource()函数取了一个默认内存资源.然后创建了一个使用该默认资源分配多态分配器.
接着使用该分配器创建了一个std::pmr::vector容器vec,并向其中添加了一些元素.最后,遍历容器输出其中的元素.

(四)自定义内存资源

用户还可自定义``std::pmr::memory_resource继承类,以实现特定的分配内存策略.如,可实现一个线本的内存池分配器,或一个基于映射文件分配内存器.

自定义内存资源示例

#include<memory_resource>#include<iostream>#include<mutex>#include<thread>classThreadLocalMemoryResource:publicstd::pmr::memory_resource{private:std::mutex mutex_;std::vector<char>buffer_;public:void*do_allocate(std::size_t bytes,conststd::size_t)override{std::lock_guard<std::mutex>lock(mutex_);buffer_.resize(buffer_.size()+bytes);returnbuffer_.data()+buffer_.size()-bytes;}voiddo_deallocate(void*ptr,std::size_t bytes,conststd::size_t)override{//不需要释放`线本内存资源`}booldo_is_equal(conststd::pmr::memory_resource&other)constnoexceptoverride{returnthis==&other;}};intmain(){//创建`自定义`内存资源ThreadLocalMemoryResource custom_resource;//创建一个使用`自定义`资源的`多态分配器`std::pmr::polymorphic_allocator<int>alloc(&custom_resource);//使用多态分配器`分配内存`std::pmr::vector<int,std::pmr::polymorphic_allocator<int>>vec(alloc);//添加元素vec.push_back(1);vec.push_back(2);vec.push_back(3);//`输出`元素for(inti:vec){std::cout<<i<<" ";}std::cout<<std::endl;return0;}

这里,定义了从std::pmr::memory_resource继承的叫ThreadLocalMemoryResource自定义内存资源类.

do_allocate函数中,按内存缓冲使用一个std::vector,每次分配内存时,将缓冲的大小增加到要求的字节数,并返回新分配内存的指针.

do_deallocate函数中,因为是线本内存资源,不需要释放内存,因此闲着.在do_is_equal函数中,比较对象的地址来判断两个内存资源是否相等.

函数中,创建了一个ThreadLocalMemoryResource对象custom_resource,并使用它创建了一个分配多态分配器.
然后使用该分配器创建了一个std::pmr::vector容器vec,并向其中添加了一些元素.最后,遍历容器输出其中的元素.

三,总结

std::pmr::memory_resourcestd::polymorphic_allocatorC++17中引入的重要的管理内存工具,它们为分配内存提供了更高的灵活性统一性.

自定义内存资源,用户可按需实现高效的管理内存策略,如在多线程环境中使用线本分配内存提高性能,或使用内存池分配来减少内存片段.

这些工具的引入使得C++管理内存方面更加强大和灵活,可更好地满足不同应用场景的需求.同时,它们也提高了代码的可维护性可扩展性,使得你可更加轻松地管理和优化内存使用.

实际应用中,可选择合适的内存资源分配器,并结合自定义内存资源,实现更加高效和灵活管理内存.

如,在对性能要求极高的场景中,可用自定义内存池分配器来减少分配和释放内存的成本;在多线程环境中,可用线本内存资源来避免线程间的竞争.
总之,std::pmr::memory_resourcestd::polymorphic_allocatorC++你提供了强大的管理内存能力,值得深入应用和探索.

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/27 6:45:39

独立开发者:Build In Public,解决产品冷启动难题

大家好&#xff0c;我是 dtsola&#xff0c;一名 IT 解决方案架构师&#xff0c;也是一人公司的实践者。 在探索独立开发和一人公司的道路上&#xff0c;我一直在思考一个问题&#xff1a;如何在资源有限的情况下&#xff0c;让自己的产品和想法被更多人看到&#xff1f; 传统…

作者头像 李华
网站建设 2026/6/10 13:24:17

四元数散度和旋度-8

先前给出了简单的三轴垂直关系。实际上只是半个三轴&#xff0c;若要补全三轴&#xff0c;则只需要在相反的方向上加一个负号&#xff0c;也就是乘以虚数单位的平方&#xff0c;比如说 z 轴的正方向相对于 x 轴的正方向要乘以 &#xff0c;那么它的负方向&#xff0c;相对于 x…

作者头像 李华
网站建设 2026/5/29 0:42:52

敲黑板!一分钟学会解析车辆VIN码

自有VIN码数据库包含三千余款车型&#xff0c;可解析车辆产地、品牌、车系、车型、车款、排量、座位数、指导价格、车型代码、燃油类型、变速箱类型、发动机型号、发动机功率等30种汽车参数&#xff0c;应用深度学习算法&#xff0c;识别速度小于0.5秒&#xff0c;识别准确率高…

作者头像 李华
网站建设 2026/5/19 22:33:36

如何使用VOFA+配合恒温箱进行温度监控?

Amanda-zh咸鱼恒温箱 Amanda-zh-XianYu_Heng_Wen_Xiang_20250105 一、如何使用VOFA查看波形数据 下载打开vofa&#xff1a; VOFA-Plus上位机 | VOFA-Plus上位机 打开后选择这几个选项&#xff0c;实际串口端口号会发生改变&#xff0c;波特率一般为115200 然后右键选择我圈…

作者头像 李华
网站建设 2026/6/9 5:56:20

机器视觉软件介绍:opencv、halcon、康耐视visionpro、海康visionmaster

OpenCV、Halcon、VisionPro、VisionMaster 优缺点对比及选型建议 以下从核心能力、开发与部署、成本与生态等维度&#xff0c;对OpenCV、Halcon、康耐视VisionPro、海康VisionMaster进行优缺点对比&#xff0c;兼顾工业场景与研发需求的差异化选择。一、核心能力与性能软件优势…

作者头像 李华
网站建设 2026/6/3 21:39:27

模型训练过程报出nan的错误

模型训练过程报出nan的错误 1 训练模型出现nan的现象 在模型训练过程中&#xff0c;我们经常会遇到损失函数的值变为nan的情况。nan表示“不是一个数字”&#xff0c;通常是由于数值计算中的错误导致的。例如&#xff0c;我们在计算损失函数时&#xff0c;可能会出现除以零、…

作者头像 李华