关于STL容器,最了不起的一点是,它们会自己主动增长以便容纳下你放入当中的数据,仅仅要没有超出它们的最大限制就能够。对于vector和string,增长过程是这样来实现的:每当须要很多其它空间时,就调用与realloc类似的操作。

这一类似于realloc的操作分为4部分:

  1. 分配一块大小为当前容量的某个倍数的新内存。

    在大多数实现中,vector和string的容量每次以2的倍数增长,即,每当容器须要扩张时,它们的容量即加倍。

  2. 把容器的全部元素从旧的内存复制到新的内存中。

  3. 析构掉旧内存中的对象。

  4. 释放旧内存。

    reserve成员函数能使你把又一次分配的次数降低到最低限度,从而避免了又一次分配内存和指针/迭代器/引用失效带来的开销。在解释reserve如何做到这一点之前。我将简单概括一下4个相互关联,但有时会被混淆的成员函数。在标准容器中,仅仅有vector和string提供了全部这4个函数:

    size()说明了改容器中有多少个元素。它不会告诉你该容器为自己所包括的元素分配了多少内存。

    capacity()说明了改容器利用已经分配的内存能够容纳多少个元素。

    这是容器所能容纳的元素总数。而不是它还能容纳多少个元素。

    假设你想知道一个vector由多少为被使用的内存,你就得从capacity()中减去size()。假设size和capacity返回相同的值。就说明容器中不再有剩余空间了。

    resize(Container::size_type n)强迫容器改变到包括n个元素的状态。

    在调用resize之后,size将返回n。

    假设n比当前的大小要小,则容器尾部的元素将会被析构掉。假设n比当前的大小要大。则通过默认构造函数创建的新元素将被加入到容器的末尾。假设n比当前的容量要大,那么在加入元素之前,将先又一次分配内存。

    reserve(Container::size_type n)强迫容器把它的容量变为至少是n。前提是n不小于当前的大小。这一般会导致又一次分配,由于容量会添加。(假设n比当前的容量小,则vector忽略该调用。什么也不做;而string则可能把自己的容量减为size()和n中的最大值,可是string的大小肯定保持不变。)

    比如:假定想创建一个包括1到1000之间的值的vector<int>。

    假设不使用reserve。你可能会这样做:

    vector<int> v;

    for (int i = 1;i <= 1000;++i)

    v.push_back(i);

    该循环在进行过程中将导致2到10次又一次分配。假设使用reserve,例如以下所看到的:

    vector<int> v;

    v.reserve(1000);

    for (int i = 1;i <= 1000;++i)

    v.push_back(i);

    则在循环过程中将不会再发生又一次分配。

假设想除去多余的容量。请參阅怎样有效除去多余的容量

版权声明:本文博客原创文章,博客,未经同意,不得转载。

使用reserve要再次避免不必要的分配的更多相关文章

  1. 条目十四《使用reserve来避免不必要的重新分配》

    条目十四<使用reserve来避免不必要的重新分配> 使用vector和string的插入元素的时候,我们是不用担心内存问题的(只要不超过容器的max_size).因为底层有分配子管理内存 ...

  2. vector 的resize 和 reserve

    首先声明,都是转载的,理解知识为主要目的. http://www.cnblogs.com/zahxz/archive/2013/02/20/2918711.html C++内置的数组支持容器的机制,但 ...

  3. C语言和C++篇

    C语言和C++篇 基本上所有主流的编程语言都有String的标准库,因为字符串操作是我们每个程序员几乎每天都要遇到的.想想我们至今的代码,到底生成和使用了多少String!标题上所罗列的语言,可以看成 ...

  4. 从C,C++,JAVA和C#看String库的发展(一)----C语言和C++篇

    转自: http://www.cnblogs.com/wenjiang/p/3266305.html 基本上所有主流的编程语言都有String的标准库,因为字符串操作是我们每个程序员几乎每天都要遇到的 ...

  5. 深入研究java.lang.Runtime类

    一.概述      Runtime类封装了运行时的环境.每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接.      一般不能实例化一个Runtime对象, ...

  6. c++中vector的用法详解

    c++中vector的用法详解 vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间 ...

  7. 浅析Java.lang.Runtime类

    一.概述      Runtime类封装了运行时的环境.每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接.      一般不能实例化一个Runtime对象, ...

  8. C++中 vector(容器)的用法

    vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间的目的. 用法: 1.文件包含: ...

  9. C++中vector的用法

    C++内置的数组支持容器的机制,但是它不支持容器抽象的语义.要解决此问题我们自己实现这样的类.在标准C++中,用容器向量(vector)实现.容器向量也是一个类模板.标准库vector类型使用需要的头 ...

随机推荐

  1. Java Metrics

    Java Metrics Java Metrics是一个功能比較强大的java统计库,它的输出组件也非常强大,帮我们做好了: 输出到Ganglia 输出到控制台 输出到JMX 输出Json 具体见:d ...

  2. Tuxedo学习门户网站

    中间件简介: 介于客户机和server之间的夹层,突破了传统的c/s架构,为构建大规模,高性能.分布式c/s应用程序提供了通信.事物,安全.容错等基础服务,屏蔽了底层应用细节,应用程序不必从底层开发, ...

  3. ListView滑动删除 ,仿腾讯QQ

    转载请表明出处:http://blog.csdn.net/lmj623565791/article/details/22961279 在CSDN上开了很多大神们的文章,感觉受益良多,也非常欣赏大家的分 ...

  4. HttpLuaModule——翻译(Nginx API for Lua) (转)

    现在我已经将翻译的内容放到:http://wiki.nginx.org/HttpLuaModuleZh Nginx API for Lua Introduction 各种各样的*_by_lua和*_b ...

  5. 如何js编译的文件dll对于网页电话

    1. 加入一个项目的解决方案:JSControl 2. 在这个项目中加入js文件(JScript1.js) 脚本的内容: function showAlert(){ alert('Today is a ...

  6. C#启动进程之Process

    在程序设计中,我们经常会遇到要从当前的程序跳到另一个程序的设计需求.也就是当前进程创建另一个进程.C#提供了Process使得我们很方便的实现. 1.Process基本属性和方法 Id //进程的Id ...

  7. [LeetCode] Search in Rotated Sorted Array II [36]

    称号 Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would t ...

  8. 为了解决这个问题:07文本WORD文档超链接、页码成{HYPERLINK&quot;网站&quot;}、{PAGE}/{NUMPAGES}

    版权声明:本文博主原创文章.博客,未经同意不得转载.

  9. Base64编码和解码

    Base64这是一个二进制编码方法转换成可打印字符.主要用于邮件传输. Base64将64人物(A-Z,a-z,0-9,+,/)由于基本字符集.把所有的符号转换成字符集. 编码: 编码每次3节转为4字 ...

  10. struts详细解释拦截器

    1.拦截器:Struts2拦截器将一个Action要么Action的方法.之前或截取后场,和Struts2拦截器是可插拔,拦截器AOP一种实现. WebWork:拦截器是动态拦截Action调用的对象 ...