C++ STL六大组件-6-Allocator(分配器)

it2023-10-17  70

C++ STL六大组件-简析

------------------------------------------

C++ STL六大组件-1-Container(容器)                           

C++ STL六大组件-2-Adapter(适配器) 

C++ STL六大组件-3-Algorithm(算法) 

C++ STL六大组件-4-Iterator(迭代器) 

C++ STL六大组件-5-Function object(函数对象) 

C++ STL六大组件-6-Allocator(分配器)

----------------------------------------------------------------------------------

C++ STL Allocator

分配器(配置器,allocator),用于分配管理内存空间。可以把allocator看成一个简易的内存池,其主要适用于在使用容器时,对内存空间的动态分配。

如果是我们平常要申请一块动态内存时,不推荐使用allocator,应该使用new-delete(malloc-free),主要原因是allocator不好用(使用不方便,容器例外),在内存释放的时候还需要提供对象的个数,因为我们在动态分配内存时候基本上都是对指针所指向的内存空间进行操作,而不会去记录空间中构造了多少个对象。

allocator的特点是将内存分配(allocate)与对象构造(construct)分离,这样使得对内存的管理更加灵活,性能较高。

allocator<string> alloc; 定义了一个可以分配string的allocator对象 auto const p=alloc.allocate(n); //分配n个未初始化的string内存,即为n个空string分配了内存,当然正如上面所说,分配的内存是原始的,未构造的。

allocator用法

allocator<T> a

定义了一个名为a的allocator对象,它可以为类型T的对象分配内存

a.allocator(n)

分配一段原始的、未构造的内存,这段内存能保存n个类型为T的对象

a.deallocate(p,n)

 释放T*指针p地址开始的内存,这块内存保存了n个类型为T的对象,p必须是一个先前由allocate返回的指针,且n必须是p创建时所要求的大小,且在调用该函数之前必须销毁在这片内存上创建的对象。要求还蛮多的哈,这是因为在创建过程中我们分配的是最原始的内存,所以在释放内存时也是只能严格释放这片最原始的内存。

a.construct(p,args)

 p必须是一个类型为T* 的指针,指向一片原始内存,arg将被传递给类型为T的构造函数,用来在p指向的原始内存上构建对象。

a.destory(p)

p为T*类型的指针,用于对p指向的对象执行析构函数。

 为什么会有allocator?

new在内存分配上面有一些局限性,new的机制是将内存分配和对象构造组合在一起,同样的,delete也是将对象析构和内存释放组合在一起。但当分配一块大块内存时,我们想要自己在这块内存上构建对象,这中情况下我们希望将内存分配和对象构造分离。使用Allocator的话,我们可以事先得到大块内存,然后真正需要时就在这块内存上创建对象。

 

Allocator注意事项

Allocator是一个函数模板,模板参数T表示你要分配内存的对象的类型,所以函数参数是分类对象的个数,而不是字节大小。一定不能让模板随着对象的不同而有不同的状态,因此,Allocator不应该有非静态成员变量。Allocator的使用是分步骤的,首先要申请内存,再在申请好的内存上进行对象构造,顺序不能反(释放对象的时候是先析构对象,再释放内存)。rebind模板的作用。Allocator模板中有一个rebind类模板,用于重新将类型进行一次绑定。比如在创建ListNode<T>节点时,传进Allocator的参数可能是T,但是真正要申请的空间大小是ListNode<T>,所以可以用Allocator::rebind<ListNode> ::other进行转换,就可以得到ListNode<T>的分配器。但是实际上,也可以直接给Allocator的是ListNode<T>,直接构造一个节点大小的空间也行。

 

参考文档

https://blog.csdn.net/u012333003/article/details/22104939https://blog.csdn.net/puliao4167/article/details/86480007
最新回复(0)