c++11 动态内存管理-分配器 (std::allocator)
定义于头文件 <memory>
template< class T >struct allocator; (1) template<>struct allocator<void>; (2) (C++17 中弃用) (C++20 中移除)
std::allocator
类模板是所有标准库容器所用的默认分配器 (Allocator) ,若不提供用户指定的分配器。默认分配器无状态,即任何给定的 allocator 实例可交换、比较相等,且能解分配同一 allocator 类型的任何其他实例所分配的内存。
对 void 的显式特化缺少成员 typedef |
(C++20 前) |
所有自定义分配器必须也无状态。 | (C++11 前) |
自定义分配器可以含有状态。每个容器或其他具分配器对象存储一个提供的分配器实例,并通过 std::allocator_traits 控制分配器替换。 | (C++11 起) |
默认分配器满足分配器完整性要求。 | (C++17 起) |
构造函数
std::allocator<T>::allocator
allocator() throw(); |
(1) | (C++11 前) |
allocator() noexcept; |
(C++11 起) (C++20 前) |
|
constexpr allocator() noexcept; |
(C++20 起) | |
allocator( const allocator& other ) throw(); |
(2) | (C++11 前) |
allocator( const allocator& other ) noexcept; |
(C++11 起) (C++20 前) |
|
constexpr allocator( const allocator& other ) noexcept; |
(C++20 起) | |
template< class U > |
(3) | (C++11 前) |
template< class U > |
(C++11 起) (C++20 前) |
|
template< class U > |
(C++20 起) |
构造默认分配器。因为默认分配器是无状态的,故构造函数无可见效应。
参数
other | - |
用以构造的另一 allocator
|
析构函数
std::allocator<T>::~allocator
~allocator(); |
(C++20 前) | |
constexpr ~allocator(); |
(C++20 起) |
销毁默认分配器。
获得对象的地址,即使重载了 operator&
std::allocator<T>::address
pointer address( reference x ) const; |
(C++11 前) | |
pointer address( reference x ) const noexcept; |
(C++11 起) (C++17 中弃用) (C++20 中移除) |
|
const_pointer address( const_reference x ) const; |
(C++11 前) | |
const_pointer address( const_reference x ) const noexcept; |
(C++11 起) (C++17 中弃用) (C++20 中移除) |
返回 x
的实际地址,即使存在重载的 operator& 。
参数
x | - | 要获取地址的对象 |
返回值
x
的实际地址。
分配未初始化的存储
std::allocator<T>::allocate
pointer allocate( size_type n, const void * hint = 0 ); |
(1) | (C++17 前) |
T* allocate( std::size_t n, const void * hint); |
(C++17 起) (弃用) (C++20 中移除) |
|
T* allocate( std::size_t n ); |
(2) |
(C++17 起) (C++20 前) |
[[nodiscard]] constexpr T* allocate( std::size_t n ); |
(C++20 起) |
调用 ::operator new(std::size_t) 或 ::operator new(std::size_t, std::align_val_t) (C++17 起)分配 n * sizeof(T) 字节的未初始化存储,但何时及如何调用此函数是未指定的。指针 hint
可用于提供引用的局部性:若实现支持,则 allocator 会试图分配尽可能接近 hint
的新内存块。
参数
n | - | 要分配存储的对象数 |
hint | - | 指向临近内存位置的指针 |
返回值
指向适当对齐并足以保有 T
类型的 n
个对象数组的内存块首字节的指针。
异常
若分配失败则抛出 std::bad_alloc 。
注解
遣词“未指定何时及如何”令标准库容器可以组合或优化掉堆分配,即使对直接调用 ::operator new
禁止这种优化。例如 libc++ 实现了它( [1] 与 [2] )
解分配存储
std::allocator<T>::deallocate
void deallocate( T* p, std::size_t n ); |
(C++20 前) | |
constexpr void deallocate( T* p, std::size_t n ); |
(C++20 起) |
从指针 p
所引用的存储解分配,指针必须是通过先前对 allocate() 获得的指针。
参数 n
必须等于对原先生成 p
的 allocate() 调用的首参数;否则行为未定义。
调用 ::operator delete(void*) 或 ::operator delete(void*, std::align_val_t) (C++17 起),但何时及如何调用是未指定的。
参数
p | - |
从 allocate() 获得的指针
|
n | - |
先前传递给 allocate() 的对象数
|
返回值
(无)
调用示例
#include <memory>
#include <iostream>
#include <string>int main()
{std::allocator<int> ai; // int 的默认分配器int* a = ai.allocate(10); // 10个 int 的空间for (int i = 0; i < 10; i++){ai.construct(a + i, i); // 构造 int}for (int i = 0; i < 10; i++){std::cout << a[i] << '\n';}ai.deallocate(a, 10); // 解分配10个 int 的空间std::allocator<std::string> as; // string 的默认分配器std::string * s = as.allocate(10); // 10个 string 的空间for (int i = 0; i < 10; i++){as.construct(s + i, std::to_string(i) + "-string"); // 构造 int}for (int i = 0; i < 10; i++){std::cout << s[i] << '\n';}as.deallocate(s, 10); // 解分配10个 int 的空间
}
输出
返回最大的受支持分配大小
std::allocator<T>::max_size
size_type max_size() const throw(); |
(C++11 前) | |
size_type max_size() const noexcept; |
(C++11 起) (C++17 中弃用) (C++20 中移除) |
返回理论上可行的 n
最大值,对于它 allocate(n, 0)
调用可能成功。
大部分实现中,它返回 std::numeric_limits<size_type>::max() / sizeof(value_type) 。
参数
(无)
返回值
受支持的最大分配大小
调用示例
#include <memory>
#include <iostream>
#include <string>struct Foo
{Foo() {}
};int main()
{std::allocator<char> ac; // char 的默认分配器std::allocator<int> ai; // int 的默认分配器std::allocator<double> ad; // double 的默认分配器std::allocator<std::string> as; // string 的默认分配器std::allocator<Foo> af; // Foo 的默认分配器std::cout << "char max_size() " << ac.max_size() << '\n';std::cout << "int max_size() " << ai.max_size() << '\n';std::cout << "double max_size() " << ad.max_size() << '\n';std::cout << "as max_size() " << as.max_size() << '\n';std::cout << "Foo max_size() " << af.max_size() << '\n';
}
输出
在分配的存储构造对象
std::allocator<T>::construct
void construct( pointer p, const_reference val ); |
(1) | (C++11 前) |
template< class U, class... Args > |
(2) |
(C++11 起) (C++17 中弃用) (C++20 中移除) |
用布置 new ,在 p
所指的未初始化存储中构造 T
类型对象。
1) 调用 new((void *)p) T(val)
2) 调用 ::new((void *)p) U(std::forward<Args>(args)...)
参数
p | - | 指向未初始化存储的指针 |
val | - | 用作复制构造函数参数的值 |
args... | - | 所用的构造函数参数 |
返回值
(无)
析构在已分配存储中的对象
std::allocator<T>::destroy
void destroy( pointer p ); |
(C++11 前) | |
template< class U > |
(C++11 起) (C++17 中弃用) (C++20 中移除) |
调用 p
所指的对象的析构函数
1) 调用 ((T*)p)->~T()
2) 调用 p->~U()
参数
p | - | 指向要被销毁的对象的指针 |
返回值
(无)
比较两个分配器实例
operator==,!=(std::allocator)
template< class T1, class T2 > |
(1) | (C++11 前) |
template< class T1, class T2 > |
(C++11 起) (C++20 前) |
|
template< class T1, class T2 > |
(C++20 起) | |
template< class T1, class T2 > |
(2) | (C++11 前) |
template< class T1, class T2 > |
(C++11 起) (C++20 前) |
比较二个默认分配器。因为默认分配器无状态,故二个默认分配器始终相等。
1) 返回 true
2) 返回 false
参数
lhs, rhs | - | 要比较的默认分配器 |
调用示例
#include <memory>
#include <iostream>
#include <string>int main()
{std::allocator<int> a1; // int 的默认分配器int* a = a1.allocate(1); // 一个 int 的空间a1.construct(a, 7); // 构造 intstd::cout << a[0] << '\n';a1.deallocate(a, 1); // 解分配一个 int 的空间// string 的默认分配器std::allocator<std::string> a2;// 同上,但以 a1 的重绑定获取decltype(a1)::rebind<std::string>::other a2_1;// 同上,但通过 allocator_traits 由类型 a1 的重绑定获取std::allocator_traits<decltype(a1)>::rebind_alloc<std::string> a2_2;std::string* s = a2.allocate(2); // 2 个 string 的空间a2.construct(s, "foo");a2.construct(s + 1, "bar");std::cout << s[0] << ' ' << s[1] << '\n';a2.destroy(s);a2.destroy(s + 1);a2.deallocate(s, 2);
}
c++11 动态内存管理-分配器 (std::allocator)相关推荐
- C和C++安全编码笔记:动态内存管理
4.1 C内存管理: C标准内存管理函数: (1).malloc(size_t size):分配size个字节,并返回一个指向分配的内存的指针.分配的内存未被初始化为一个已知值. (2).aligne ...
- 《C++应用程序性能优化::第五章动态内存管理》学习和理解
<C++应用程序性能优化::第五章动态内存管理>学习和理解 说明:<C++应用程序性能优化> 作者:冯宏华等 2007年版. 2010.8.29 cs_wuyg@126.com ...
- 【C++】动态内存管理/move/以及移动构造与移动赋值运算符
文章目录 1 .对象移动与右值引用 实际应用过程中遇到的问题及其解决方案 c++中临时变量不能作为非const的引用参数 2. 动态内存管理类 3. 对象移动与右值引用 4. 移动构造与移动复制运算符 ...
- LwIP 之五 详解动态内存管理 内存堆(mem.c/h)
写在前面 目前网上有很多介绍LwIP内存的文章,但是绝大多数都不够详细,甚至很多介绍都是错误的!无论是代码的说明还是给出的图例,都欠佳!下面就从源代码,到图例详细进行说明. 目前,网络上多数文 ...
- C++ 动态内存管理:c/c++的动态内存管理,new/delete,operator new/delete,placement-new, 内存泄漏
c/c++的动态内存管理 new/delete opeartor new/delete placement-new 内存泄漏 c/c++的动态内存管理 在开始之前首先要了解c和c++的内存分布,我简单 ...
- C语言程序设计 | 动态内存管理:动态内存函数介绍,常见的动态内存错误,柔性数组
动态内存管理目录: 动态内存函数的介绍 常见的动态内存函数的错误 柔性数组 为什么会有动态内存管理呢 我们在日常使用中,创建一个数组,一个变量时都会开辟空间 如: int a; //在栈上开辟一个四字 ...
- 内存区划分;内存分配;堆、栈概念分析;动态内存管理数据结构及程序样例;核心态与用户态...
一. 在c中分为这几个存储区1.栈 - 由编译器自动分配释放 2.堆 - 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 3.全局区(静态区),全局变量和静态变量的存储是放在一块的,初 ...
- 析构函数和动态内存管理
析构函数 当类的对象撤销时,析构函数被隐式调用.析构函数不是释放内存,而是释放内存前进行扫尾工作. 对象何时撤销?1,静态分配的,生存期过后撤销.2,动态分配的,delete时撤销. 析构函数的命名 ...
- C ++ 内存 | C/C++的动态内存管理_1
C/C++的动态内存管理 1. C语言中,我经常会用到动态内存管理的三个命令: malloc calloc rolloc free (1)malloc 用来申请head内存空间的内存. (2)call ...
最新文章
- Permission denied: make_sock: could not bind to address [::]:81 Apache 虚拟主机
- 同时起两个mysql 起不了_到底是谁!让你在冬天的早晨起不了床?
- 空指针异常是什么原因_睡觉时,突然抖了一下,脚踏空,是什么原因?
- 用“龙头”促发展,以“立体”筑生态,长沙生物医药产业集群跑出“加速度”
- 9.整型安全操作.rs
- 《JavaScript 高级程序设计》笔记 第1~5章
- php登录注册脚本,PHP - 登录脚本
- Unity根据电脑高中低配置加载不同模型
- 计算机 学校教一半 自学一半,一半初中生无缘普高,上职业学校怎么样?
- 【思维导图】nav_msgs/Odometry 消息的构成及订阅
- jeesite如何已生成数据的数据源_jeesite 多数据源配置
- MySQL高可用之MHA的搭建 转
- ConceptDraw Office for mac(跨平台图表办公程序)
- Screaming Frog SEO Spide如何解决IIS 10中缺少CS协议支持的问题
- 前端CSS - 相对定位,绝对定位,固定定位
- 计算机应用教程卢湘鸿,计算机应用教程
- DCMTK各模块说明
- 怎么用python输出百分比_Python 输出百分比
- 苦橙花---不喧哗,自有声
- 深度:企业为什么需要一个平台级的OA产品?
热门文章
- sql 语句换行 +
- 又一随机视频聊天网站内侧了,名字叫QQ偶遇,地址为:http://qq.17ouyu.com/
- python中permute_Pytorch之permute函数
- 过来人的经验:Java实习生在公司里一般都做什么?
- Python生成一张图片让iphone屏幕秒变随身直尺
- pywifi 控制wifi
- Java性能优化推荐书!mongodbmysql迁移
- Max删除时间范围外的帧——DeleteKeysOutOfRange
- [项目]SSM+Vue智能点餐系统
- docker进行ElasticSearch集群部署