映射和设置总是一次分配一个项目吗

Do map and set allocate 1 item at a time always?

本文关键字:分配 项目 一个 一次 设置 映射      更新时间:2023-10-16

我正在C++14中实现std::mapstd::set的分配器。分配器必须提供一个函数pointer allocate(size_type n),该函数一次为n项分配空间。

经过一些测试,我看到std::mapstd::set在我的平台上总是做allocate(1),我没有看到任何n > 1。如果我考虑一下内部的树表示,这对我来说是有意义的。

标准能保证这种行为吗?或者,我可以放心地在任何特定平台中始终信任n == 1吗?

标准是否保证这种行为

没有。该标准不能保证这一点。

或者我可以在任何特定平台中始终安全地信任n=1吗

指令插入时的分配数量受到容器方法复杂性的限制。例如,对于std::map::insert,标准指定(从cppreference,只有前3个重载,插入单个元素):

1-3)容器大小的对数,O(log(size()))。

然后实现者可以自由选择满足此规范的实现。log(size())部分是因为你需要找到插入的地方,为固定数量的元素分配空间只是对复杂性的一个持续贡献。实现可以选择在每次调用时为两个元素分配空间。2和1一样恒定。然而,在绝对值上,不难找到分配1比分配2更有效的情况。此外,std::mapstd::set不需要将它们的元素存储在连续存储器中。

因此,我假设它总是1,但你不能保证。如果你想确定,你必须看看具体的实现,但你依赖于实现的细节。

CCD_ 14与CCD_

A::allocate(n)必须返回一个指针,因此分配非连续内存并非易事。然而,不要求该指针是T*。相反,CCD_ 18返回一个CCD_。这可以是任何类型,只要它满足NullablePointerLegacyRandomAccessIteratorLegacyContiguousIterator即可。

cppreference提到boost::interprocess::offset_ptr作为如何分配分段内存的示例。你可能想看看。以下是完整报价:

花式指针

当成员类型指针不是原始指针类型时,通常被称为"花式指针"。这样的指针被引入支持分段内存体系结构,目前用于访问在不同于同构的地址空间中分配的对象由原始指针访问的虚拟地址空间。示例花式指针是与映射地址无关的指针boost::interprocess::offset_ptr,这使分配成为可能基于节点的数据结构,如共享内存中的std::set和在每个进程中映射到不同地址的内存映射文件。花式指针可以独立于分配器使用通过类模板std::pointer_traits提供了它们。