使用allocator分离动态内存申请和对象构造
2023年12月29日 2023年12月29日
创建allocator对象
默认初始化
1allocator<T> a;
申请整块动态内存, 足以容纳指定个数的元素
allocate
- 动态内存是原始的、未构造的
- 返回值为指向这片动态空间的内置指针
- 需另外保存指针和对象个数
1T *p = a.allocate(n);
有序构造动态对象
construct
使用args在p指向的原始动态内存构造动态对象
1a.construct(p, args);
逆序析构动态对象
destroy
对p指向的动态对象调用析构函数
1a.destroy(p);
归还整块动态内存
deallocate
用到申请整块动态内存后保存的指针和对象个数:
- p为allocate的返回值
- n为传给allocate的动态对象个数
p、n不具有灵活性
调用deallocate之前,保证对象已被析构
1a.deallocate(p, n);
示例
1allocator<string> alloc; 2auto n = 10; 3auto start = alloc.allocate(n), cur = start; // 申请动态内存; 保存start,调用deallocate时使用;cur指向未构造对象 4 5 // 有序构造动态对象 6alloc.construct(cur++); // 空串 7alloc.construct(cur++, 10, 'c'); // 10个'c' 8alloc.construct(cur++, "hi"); // "hi" 9 10while (cur != start) 11 alloc.destroy(--cur); // 逆序析构动态对象 12 13alloc.deallocate(start, n); // 归还动态内存空间
使用泛型算法初始化allocator管理的动态内存
输入序列有两种:
-
接受迭代器范围表示的输入序列
[b, e]
-
给出指向输入序列首元素的迭代器和输入序列元素个数
[b, b + n)
使用输入序列构造动态对象
cur为输入迭代器, 指向待构造对象
默认allocator管理的动态内存足够容纳待构造元素
返回指向待构造对象的内置指针
1uninitialized_copy(b, e, cur); 2 3uninitialized_copy_n(b, n, cur);
将输入序列中的元素构造为给定对象的拷贝
t为给定对象; 将输入序列中的每一个元素构造为给定对象的拷贝
默认输入序列有效
- 返回void
1uninitialized_fill(b, e, t);
- 返回内置指针
b + n
1uninitialized_fill_n(b, n, t);
示例
1#include <iostream> 2#include <vector> 3#include <memory> 4 5void Print_Allocator_Int(int *b, int *e) { 6 for (auto i = b; i != e; i++) 7 std:: cout << *i << " "; 8 std::cout << std::endl; 9} 10 11int main() { 12 std::vector<int> ivec{0, 1, 2, 3, 4, 5}; 13 std::vector<int> ivec2{10, 11, 12, 13, 14, 15}; 14 15 std::allocator<int> alloc; 16 auto begin = alloc.allocate(ivec.size() * 5), cur = begin; 17 18 alloc.construct(cur++, 100); 19 // 构造1个元素, 100 20 21 cur = std::uninitialized_copy(ivec.begin(), ivec.end(), cur); 22 // 构造6个元素, 0, 1, 2, 3, 4, 5 23 24 cur = std::uninitialized_copy_n(ivec2.begin(), 6, cur); 25 // 构造6个元素, 10, 11, 12, 13, 14, 15 26 27 std::uninitialized_fill(cur, cur + 5, 99); 28 cur += 5; 29 // 构造5个元素: 99, 99, 99, 99, 99 30 31 cur = std::uninitialized_fill_n(cur, 5, 100); 32 // 构造5个元素: 100, 100, 100, 100, 100 33 34 Print_Allocator_Int(begin, cur); 35 36 return 0; 37}
输出
100 0 1 2 3 4 5 10 11 12 13 14 15 99 99 99 99 99 100 100 100 100 100