C++ STL和泛型编程(二)----分配器(allocators)

一、OOP vs. GP

  • OOP: Object-Oriented programming

在这里插入图片描述OOP一般将数据和操作数据的函数放在同一个类里进行,然后再通过各种继承关系进行运作。
这里list没有RandomAccessIterator,所以不能用全局的::sort()进行排序,因为全局的sort()要求传入的指针参数,可以随意加减变化的,而list容器里的指针只能是由上一个指向下一个而不能随意操作如*(first+(last-first)/2)。因此list的sort()要自己在类内定义声明。

  • GP: Generic Programming

在这里插入图片描述GP将da’ta和操作data的methods分开来,容器vector存放数据,若需要对容器里的数据进行排序,则通过迭代器beging(),end()调用算法::sort()进行操作
这里容器vector和deque都提供RandomAccessIterator,所以可以直接调用全局的::sort()函数,且这里::sort()重写了两个版本。

Containers和Algorithms团队可各自闭门造车,以Iterator沟通即可;
Algorithms通过Iterators确定操作范围,并通过Iterators取用Container元素。

Algorithms:
在这里插入图片描述

二、分配器allocators

无论在何种编译器下,allocators最终底层调用的都是operator new()\operatore delete(),而更底层的调用则是malloc()/free()。

而malloc()所分配的内存大小,实际上是有额外的东西的,如cookie等额外的开销,所以分配器的各种定义使用影响分配空间的效率:

在这里插入图片描述

- (1)在VC下:

  • 对allocator的使用:
    在这里插入图片描述

  • 底层实现
    在这里插入图片描述在这里插入图片描述

从底层可以看到,调用的是operator new(),最终调用的是malloc()。

由pointer allocate(size_type _N, const void*)知,若想不通过容器直接调用allocator,则传入参数应为元素个数以及对应的一个空指针类型参数。所以为int* p = allocator().allocate(512,(int*)0);
这里 类型名+() 是表示创建一个临时对象的意思,allocator()

- (2)在BC下:

  • 对allocator的使用
    在这里插入图片描述

  • 底层实现

在这里插入图片描述

这里绕过容器直接使用allocator时,无需指定第二参数,因为其默认值为0:
pointer allocate(size_type n, allocator<void>::const_pointer = 0 )
则 int* p = allocator<int>().allocate(512)

- (3)在G2.9下:

  • 标准库定义
    在这里插入图片描述
  • 对allocator的使用:
    在这里插入图片描述
    虽然在G2.9下定义了allocate,但实际上使用时用的是alloc
    void* p = alloc::allocate(512)或alloc().allocate(512);
    在这里插入图片描述
    1.alloc实现如下,设计了16条链表,其目的是事先malloc好一个带有额外信息如cookie的空间,而且每条链表负责为8的倍数关系,#0表示大小为8,#1表示大小为16,…,#15表示大小为128(16*8)。所有容器需要内存时,都会来向alloc要内存。
    2.因为malloc是给需要分配不同大小的内存空间的,所以malloc需要包含cookie等信息的额外空间开销;但是在容器中,因为每个元素大小是一致的,所以在考虑是否可以尽量少地调用malloc。因为放进容器地元素大小相同,可考虑尽量省去cookie等信息。
    3.若此时容器需要放入地元素大小为50,则调整为56,然后找下#6链表有没挂内存块,如果没有则调用malloc()分配一个带cookie等额外开销的内存,然后切割成一份份用单向链表串起来,所以切出来的每一小块内存块都不带cookie。用这些内存块来放置元素,这样就不用为容器的每一个元素都malloc出包含cookie等信息额外空间开销的内存。

- (4)在G4.9下:

  • 对allocator的使用:
    在这里插入图片描述
  • 底层的使用:
    在这里插入图片描述在G4.9下的alloc变成了__pool_alloc:
    在这里插入图片描述则在G4.9下想调用alloc时,可指定第二参数即allocator为 __gnu_cxx::__pool_alloc<string> :
    vector<string, __gnu_cxx::__pool_alloc<string>> vec;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值