当前位置:网站首页>STL容器自定义内存分配器
STL容器自定义内存分配器
2022-08-02 14:07:00 【3A是个坏同志】
STL 和 STL 扩展类现在接受额外的模板分配器参数。分配器参数的默认值来自C++标准库std::allocator<T>。您也可以提供自己的分配器,以便在应用程序中自定义内存管理。为了提供您自己的模板类作为分配器,模板必须符合特定接口,包括成员函数和类型定义以及其句法和语义要求。
下面是一个简单的分配器的部分代码片段:
template <class T>
class my_allocator
{
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
template <class U>
struct rebind { typedef allocator<U> other; };
// remaining member functions described below
// ...
};rebind成员允许容器为某些任意数据类型构建分配器,分配器类型由模板参数确定。例如,容器可能需要分配 T 以外的类型(比如list节点或hash buckets)。在这种情况下,容器可以获得正确的类型,通常使用typedef:
typedef A::rebind<Node>::other Node_Allocator;
分配器模板类需满足上述要求。另外还需要实现下列函数:
构造函数
my_allocator() throw();
my_allocator (const allocator&) throw ();
template <class U>
my_allocator(const my_allocator<U>&);析构函数
~my_allocator();
分配运算符
template <class U>
my_allocator& operator=(const my_allocator<U>&) throw();public成员函数
pointer address(reference r) const;返回一个指针类型的地址。此函数和下面这个函数用于将引用r转换为指针。
const_pointer address(const_reference r) const;pointer allocate(size_type n,
allocator<U>::const_pointer hint=0);分配n个值的存储空间。如果可以,使用hint的值优化存储位置。
void deallocate(pointer);析构一块存储空间(和allocate是成对的)。
size_type max_size();返回最大的可用存储空间(allocate可用的存储空间)。
void construct(pointer p, const_reference val);在特定位置(p的位置)构造类(模板参数T)的对象,并在调用T的构造函数时使用val的值。
void destroy(pointer p);对p指向的值调用析构函数。
下面的示例定义了一个简单的自定义分配器。这可以用来测试编译器或标准C++库对自定义分配器的支持。它检查代码中传递的分配器参数是否实际使用:
#include <rw/tvdlist.h>
#include <rw/cstring.h>
#include <iostream>
template <class T>
class my_allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
my_allocator() {}
my_allocator(const my_allocator&) {}
pointer allocate(size_type n, const void * = 0) {
T* t = (T*) malloc(n * sizeof(T));
std::cout
<< " used my_allocator to allocate at address "
<< t << " (+)" << std::endl;
return t;
}
void deallocate(void* p, size_type) {
if (p) {
free(p);
std::cout
<< " used my_allocator to deallocate at address "
<< p << " (-)" <<
std::endl;
}
}
pointer address(reference x) const { return &x; }
const_pointer address(const_reference x) const { return &x; }
my_allocator<T>& operator=(const my_allocator&) { return *this; }
void construct(pointer p, const T& val)
{ new ((T*) p) T(val); }
void destroy(pointer p) { p->~T(); }
size_type max_size() const { return size_t(-1); }
template <class U>
struct rebind { typedef my_allocator<U> other; };
template <class U>
my_allocator(const my_allocator<U>&) {}
template <class U>
my_allocator& operator=(const my_allocator<U>&) { return *this; }
};
int main()
{
const int numItems = 100;
std::cout << "\nCreating a RWTValDlist with a default allocator"
<< std::endl;
RWTValDlist<RWCString> regular;
std::cout << "\nInserting " << numItems
<< " items" << std::endl;
for (int i = 0; i < numItems; ++i) {
regular.insert(RWCString('a' + i, i));
}
std::cout << "\n\nCreating a RWTValDlist with my_allocator type"
<< std::endl;
RWTValDlist<RWCString, my_allocator<RWCString> > custom;
std::cout << "\nInserting " << numItems
<< " items\n" << std::endl;
for (int i = 0; i < numItems; ++i) {
custom.insert(RWCString('a' + i, i));
}
return 0;
}程序输出:
Creating a RWTValDlist with a default allocator
Inserting 100 items
Creating a RWTValDlist with my_allocator type
used my_allocator to allocate at address 0080ABD0 (+)
used my_allocator to allocate at address 0080AC08 (+)
Inserting 100 items
used my_allocator to allocate at address 0080AC40 (+)
used my_allocator to allocate at address 0080AC78 (+)
used my_allocator to allocate at address 0080C6F0 (+)
used my_allocator to allocate at address 0080C728 (+)
used my_allocator to allocate at address 0080FB28 (+)
used my_allocator to allocate at address 00820068 (+)
used my_allocator to deallocate at address 00820068 (-)
used my_allocator to deallocate at address 0080FB28 (-)
used my_allocator to deallocate at address 0080C728 (-)
used my_allocator to deallocate at address 0080C6F0 (-)
used my_allocator to deallocate at address 0080AC78 (-)
used my_allocator to deallocate at address 0080AC40 (-)
used my_allocator to deallocate at address 0080AC08 (-)
used my_allocator to deallocate at address 0080ABD0 (-)
可以看到,当没有使用自定义分配器时,正常创建了RWTValDist并插入了100个项。当使用my_allocator实例化列表时,my_allocator的实例被用于堆内存的8次分配和解分配。
边栏推荐
- 一文带你快速掌握Kotlin核心技能
- LLVM系列第十八章:写一个简单的IR处理流程Pass
- In the Visual studio code solutions have red wavy lines
- MapReduce流程
- ConstraintLayout从入门到放弃
- The problem that UIWindow's makeKeyAndVisible does not call viewDidLoad of rootviewController
- 每周招聘|PostgreSQL专家,年薪60+,高能力高薪资
- 基于ThinkPHP6.0 - 宝塔搭建漫画CMS管理系统源码实测
- mysql
- 【目标检测】YOLO v5 吸烟行为识别检测
猜你喜欢
随机推荐
想做好分布式架构?这个知识点一定要理解透彻
VS Code远程开发及免密配置
十分钟带你入门Nodejs
加强版Apktool堪称逆向神器
binlog与iptables防nmap扫描
华为路由交换
数据乱码问题—更改mysql字符编码
MySQL知识总结 (十) 一条 SQL 的执行过程详解
mysql常用函数
执行npm install有错误error
拥抱Jetpack之印象篇
2.RecyclerView基本使用
App signature in flutter
checkPermissions Missing write access to /usr/local/lib
什么?都0202年了,你还不会屏幕适配?
【目标检测】YOLO v5 吸烟行为识别检测
7.如何给RecyclerView添加Click和LongClick事件
Ehcache基础学习
1.RecyclerView是什么
AAPT: error: duplicate value for resource ‘attr/xxx‘ with config ‘‘, file failed to compile.









