关于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. 十步完全理解SQL(转)

    本文由 伯乐在线 - 水果泡腾片 翻译.未经许可,禁止转载!英文出处:Lukas Eder.欢迎加入翻译组. 很多程序员视 SQL 为洪水猛兽.SQL 是一种为数不多的声明性语言,它的运行方式完全不同 ...

  2. singleton pattern

    1 normal mode class Singleton { private Singleton(){}; Singleton singleton; static Singleton getInst ...

  3. 【转】Android Web Server

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://vaero.blog.51cto.com/4350852/1188602 Andr ...

  4. socket计划编制的原则

    socket编程原理 1.问题的引入 1) 普通的I/O操作过程: UNIX系统的I/O命令集,是从Maltics和早期系统中的命令演变出来的,其模式为打开一读/写一关闭(open-write-rea ...

  5. Codeforces 484E Sign on Fence(是持久的段树+二分法)

    题目链接:Codeforces 484E Sign on Fence 题目大意:给定给一个序列,每一个位置有一个值,表示高度,如今有若干查询,每次查询l,r,w,表示在区间l,r中, 连续最长长度大于 ...

  6. 使用HTML5 Canvas做些什么

    百分比圆环进度条   // ----------------------------------------------------------- 柱状排行榜统计图   // ------------ ...

  7. Channel Allocation (poj 1129 dfs)

    Language: Default Channel Allocation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12 ...

  8. Lua Development Tools (LDT)

    http://www.eclipse.org/ldt/ Lua Development Tools (LDT) is about providing Lua developers with an ID ...

  9. MonkeyRunner源代码分析Android通信设备

    正如前面<谁动了我的截图?--Monkeyrunner takeSnapshot方法源代码跟踪分析>所述,本文主要会尝试描写叙述android的自己主动化測试框架MonkeyRunner到 ...

  10. 一个可以跑的Hadoop的WordCount程序

    搭个新环境时总要折腾一下,于是干脆记下来. 程序: package com.my; import java.io.IOException; import java.util.Iterator; imp ...