首页 > 解决方案 > vector::reserve 和经典内存分配的内存分配区别

问题描述

我知道向量和动态内存分配都使用堆。

char *n = new char[5000000000];

我可以观察到分配的内存增加了大约 700mb。

    vector<char> v;
    v.reserve(5000000000);

在这种情况下,它增加了超过 4GB。

这两种方法有区别吗?

标签: c++vectorstdheap-memory

解决方案


以下所有标准参考均指N4659:2017 年 3 月 Kona 后工作草案/C++17 DIS


[vector.capacity]/3

void reserve(size_type n);

效果:通知 avector计划的大小更改的指令,以便它可以相应地管理存储分配。之后 reserve()capacity()大于或等于是否发生重新分配的论点 reserve;并且等于之前的 capacity()否则的值。当且仅当当前容量小于 的参数时,才会在此时发生重新分配reserve()。如果不是由非类型的移动构造函数引发异常CopyInsertable,则不会产生任何影响。

给定的(编译器)实现可以自由地实现自己的(通常是摊销的)增长策略,并且我们在分析std::vector对象增长时可以使用的唯一保证是capacity()调用后的reserve()大于或等于传递给reserve()函数的参数。即,不允许实现分配少于提供的(要求的)参数,即使它可以通过一些聪明的程序分析实现分配的存储的部分永远不会被使用。

然而,当使用new-expression分配内存时,有许多特殊规则,由[expr.new]/10[expr.new]/12 管理允许实现者在如何分配内存方面有更大的自由度执行新表达式;例如来自 [expr.new]/10 [extract]:

允许实现省略对可替换全局分配函数([new.delete.single]、[new.delete.array])的调用。当它这样做时,存储由实现提供或通过扩展另一个new-expression的分配来提供。如果[ ... e1 ]e2

根据特定程序的上下文,这可以解释为什么与调用new char[5000000000]相比,表达式结果的动态内存占用更小。v.reserve(5000000000)


推荐阅读