std::vector/编程书籍神话的默认大小
Default size of std::vector / Programming books myth?
在一本名为";C++für C程序设计器";(C++适用于C程序员,duh!(作为参考,我在关于STL的章节中找到了以下部分(我马上为你们翻译(:
大多数STL实现在内存管理方面都很慷慨。对于实例,向量的分配大多以1kb的块来完成。如果分配了几个向量,剪切并不重要,但如果创建了10到100个向量,剪切就会重要。
我找不到任何消息来源证实这一点。我知道这取决于实现,但我找不到任何东西来证实哪怕是一个平台。Cplusplus.com仅声明:
[…]
因此,与阵列相比,矢量消耗更多的内存,以换取管理存储和以高效方式动态增长的能力。
到目前为止我试过什么
我写了一个利用OSX特定malloc_size((函数的C++程序,但我从未使用过它,我很确定我做错了。如果我做了一些类似的事情:
std::vector<int>* i = new std::vector<int>;
std::cout << malloc_size(i) << std::endl;
我只是告诉我32
,这很可能是一个整数的大小,因此证明了作者的部分错误,但我自己的努力并没有说服我。
有人更了解或了解资源吗?提前谢谢。
谨致问候,Carson
您的代码无法测量您想要测量的内容。vector
结构本身通常相当小。它基本上包含一些跟踪分配的内存所必需的字段和指向该内存的指针。你想要测量的是不同的。
------ -------------------
| i |------> | A few fields |
------ | (e.g., size and |
| capacity) | -------------------
|-----------------| | Space allocated |
| pointer |-------> | for elements |
------------------- -------------------
^ ^
What your code What you want to
measures measure
您可能可以为vector
提供一个自定义分配器,用于跟踪和报告请求的分配大小。我的计算机上的GCC 4.8.1实现没有为默认构建的向量分配内存(因为它没有元素(,并在注释中指出的每个增长实现上使用双倍大小。
矢量对象本身只有几个指针,所以您显示的32字节大小并不奇怪,而且不会随着时间的推移而改变。
我相信这本书的文本是指为向量的内容分配的存储空间。当您将项目添加到向量中时,它会分配空间来存储它们,但该空间不会反映在malloc_size中。
通过调用向量的capacity()
方法,可以计算出向量分配了多少空间。这会告诉你它能装多少件物品。如果需要以字节为单位的大小,则可以将容量乘以元素类型的大小。
引用的文本谈到了大约1 KB的块。旧的动态容器在需要增长时使用线性方案。但是标准对std::vector的运行时复杂性要求不允许这种方法。相反,矢量必须按其当前大小的某个百分比增长。
许多实现使用100%。因此,如果一个向量目前有10个项目的空间,并且需要增长,它将调整多达20个项目的大小。如果它需要进一步增长,它将调整多达40个项目的大小,以此类推。因此,在最坏的情况下,你可能会得到一个向量,它分配的空间几乎是实际需要的两倍。有些实现使用50%,这仍然满足运行时复杂性要求,而不会增长得那么快或"浪费"那么多空间。(使用小于100%的因子至少还有一个其他优点,但与本讨论无关。(
在具有虚拟内存的现代计算机上,任何一种方法通常都很好——性能将比未使用的内存更重要。如果你在一个资源有限的嵌入式系统上,你可能想要进行更直接的控制。有一些技巧,如复制和交换,可以将具有多余容量的向量修剪到接近实际需要的大小。
这本书在很多方面都不正确。std::vector
根据几何级数增长,因此将始终填充一定的百分比(除非使用erase
元素(。剪辑可能会相加,但一般来说,它与实际使用的内存成正比。50-65%是实际使用的馏分的典型最坏情况下限。
这与实现无关。需要几何级数来确保push_back
占用O(1(的摊销时间。线性增长将导致O(N(的摊销时间(或O(N^2(到push_back
的N值序列(。
实现可以为非空的vector
决定一个不可忽略的最小大小,但没有充分的理由这样做,因为小的是常见的。同样,默认的初始化向量总是被实现为根本不保留动态内存。
您不需要malloc_size
来了解保留了多少内存。只需使用v.capacity()
* sizeof( elem_type )
。
- 具有动态大小的特征矩阵的默认初始状态
- 如何使用C 11样式非默认构造分配器指定初始大小
- 固定大小和零启动数组作为C 11中的默认参数
- 默认堆栈大小
- 创建带有括号的 std::vector 作为默认大小
- 默认矢量内存大小
- C++:为什么 boost::p tr_vector 调整大小需要对象具有默认构造函数
- 如何在MFC中设置对话框的默认大小(以像素为单位)
- size_t的正确形式(传递-1作为默认值以获得最大大小)
- magik++api中用于调整大小的默认过滤器类型
- 默认动态内存大小
- 访问Ximea相机并使用OpenCV设置预定义的分辨率时,由于相机默认分辨率的大小为Mat,因此显示混乱的输出
- 为什么无法创建堆栈大小小于默认大小的线程
- libstdc++ 中的默认缓冲区大小为 basic_filebuf
- 使用一元调整大小来减小非默认可构造元素的容器的大小
- 可变参数(包大小为N)和默认参数
- malloc创建std::queue时的默认大小
- 如何在QT设计器或QT创建器中恢复按钮的默认大小
- std::vector/编程书籍神话的默认大小
- 如何调整Qwidget的大小,使其大于默认大小