【发布时间】:2016-10-24 05:42:07
【问题描述】:
使用 g++ 5.4 编译器和 GNU 标准库 libstdc++.so.6,std::vector 的默认构造函数创建一个空容器,仅初始化堆栈上的内部簿记数据成员。它稍后在堆上为数据元素分配缓冲区(当插入第一个元素时)。直到最近,我还认为这是任何具有动态分配内存的标准顺序容器的常见行为。
但是,std::deque 的工作方式不同。跟踪以下代码
#include <deque>
int main() {
std::deque<int> d;
return 0;
}
ltrace 给予
__libc_start_main(0x4024fa, 1, 0x7ffd088be0f8, 0x405bd0 <unfinished ...>
_ZNSt8ios_base4InitC1Ev(0x608351, 0xffff, 0x7ffd088be108, 160) = 0
__cxa_atexit(0x401f20, 0x608351, 0x608210, 0x7ffd088bded0) = 0
_Znwm(64, 8, 0, 8) = 0x7b4c20
_Znwm(512, 128, 0, 128) = 0x7b4c70
_ZdlPv(0x7b4c70, 0x7b4c70, 128, 0x7b4c70) = 1
_ZdlPv(0x7b4c20, 0x7b4c20, 8, 0x7b4c20) = 0
_ZNSt8ios_base4InitD1Ev(0x608351, 0, 0x401f20, 0x7fc6d4567d10) = 0x7fc6d4b00880
+++ exited (status 0) +++
_Znwm 是operator new 的实现(请参阅this)。
考虑到 STL 实现头 bits/stl_deque.h 中的 internal structure of std::deque 和 #define _GLIBCXX_DEQUE_BUF_SIZE 512 行,可以得出结论,_Znwm(64, 8, 0, 8) 为 8 个指针分配了 std::deque 的映射,_Znwm(512, 128, 0, 128) 分配了 512 字节的一块。
问题是:为什么不推迟分配这 512 个字节,直到插入 std::deque 中的第一个元素?
【问题讨论】:
-
你确定你的主要陈述按照 C++ 标准是正确的吗?
-
我具体描述了我的实现。
-
也许您可以将该信息添加到您的问题中。
-
在问题的开头添加了请求的信息。
-
我认为推迟内存分配也有利有弊。如果内存分配被推迟到第一个元素被插入,那么这意味着如果在关键路径中有插入,则无法避免内存分配中引入的延迟,因为
deque::reserve()不存在(而vector::reserve()存在) .但是如果在构造deque的时候就完成了初始内存分配,程序员可以在关键路径之外创建deque。
标签: c++