c++ - 标准容器如何为其节点(内部结构)分配内存?
问题描述
我无法弄清楚 std::set 和 std::map 如何为它们的节点分配内存,如果它们具有类型的分配器
std::allocator<Key>
和
std::allocator<std::pair<const Key, T> >
分别。据我猜测,std::set 中应该有这样的代码,例如:
std::pair<iterator, bool> insert(const value_type& value)
{
...
Node * node = new Node();
node->value = value;
...
return InsertNode(node);
}
或者
std::pair<iterator, bool> insert(const value_type& value)
{
...
Node * node = new Node();
node->p_value = a1.allocate(1);
*(node->p_value) = value;
...
return InsertNode(node);
}
其中 Node 是一些内部结构,例如红黑树节点。
那么问题来了,这个 Node 内存是如何分配的呢?
解决方案
C++ 中的分配器(出于某种原因)应该是类型化的。也就是说,特定的分配器类实例分配特定类型的对象。
但是,由于容器可能需要分配的实际类型可能与容器的值类型(容器逻辑包含的类型)不同,因此分配器(大多数情况下)需要能够转换为分配对象的备用分配器实例任何其他类型。这个过程称为“重新绑定”,它是通过调用来启动的allocator.rebind<U>
,其中U
是系统想要实际分配的类型。
作为原始分配器的反弹形式的新分配器实例必须从与原始分配器相同的内存池进行分配。因此,重新绑定被视为基于类型的更改,而不是真正不同的对象。
标准库容器的实现不允许使用new
or delete
; 它们在分配的内存中的所有动态解除/分配和对象创建/销毁都必须通过分配器执行。
当std::set<T>
插入一个项目时,它会将您的分配器重新绑定到某个节点类型,该节点类型内部包含一个T
自身或足够正确对齐的存储以创建一个T
内部。然后它将使用分配器的接口来创建该节点类型并初始化T
它包含的。std::map
有点复杂,但本质上它的节点类型必须存储 aKey
和 a Value
。
推荐阅读
- r - 循环以将列中的数据与不重叠的 NA 组合起来
- javascript - 如何将图像作为纹理加载到three.js中的层模型
- lua - 通过 Outlook 发送邮件到 lua
- r - 新分支中的更改正在保存到文件中(并反映在主分支中
- search-engine - 谷歌搜索引擎:如何搜索模式
- sdk - 我们可以使用 tableau sdk 在 tableau server 上发布数据源吗?
- php - Wordpress admin-ajax.php 错误请求 400
- azure - Azure 可以触发本地脚本按计划运行吗?
- javascript - 用于嵌套 api 调用的 Angular 6 mergeMap
- swift - 在 tableViewCells 中通信 btw collectionViews。这个 tableView 在另一个 tableViewCell