很多初学者分不清楚 vector 容器的容量(capacity)和大小(size)之间的区别,甚至有人认为它们表达的是一个意思。本节将对 vector 容量和大小各自的含义做一个详细的介绍。

vector 容器的容量(用 capacity 表示),指的是在不分配更多内存的情况下,容器可以保存的最多元素个数;而 vector 容器的大小(用 size 表示),指的是它实际所包含的元素个数。

对于一个 vector 对象来说,通过该模板类提供的 capacity() 成员函数,可以获得当前容器的容量;通过 size() 成员函数,可以获得容器当前的大小。例如:

  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4. int main()
  5. {
  6. std::vector<int>value{ 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47 };
  7. value.reserve(20);
  8. cout << "value 容量是:" << value.capacity() << endl;
  9. cout << "value 大小是:" << value.size() << endl;
  10. return 0;
  11. }

程序输出结果为:

value 容量是:20
value 大小是:15

结合该程序的输出结果,图 1 可以更好的说明 vector 容器容量和大小之间的关系。


图 1 vector 容量和大小的区别

显然,vector 容器的大小不能超出它的容量,在大小等于容量的基础上,只要增加一个元素,就必须分配更多的内存。注意,这里的“更多”并不是 1 个。换句话说,当 vector 容器的大小和容量相等时,如果再向其添加(或者插入)一个元素,vector 往往会申请多个存储空间,而不仅仅只申请 1 个。

一旦 vector 容器的内存被重新分配,则和 vector 容器中元素相关的所有引用、指针以及迭代器,都可能会失效,最稳妥的方法就是重新生成。

举个例子:

  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4. int main()
  5. {
  6. vector<int>value{ 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47 };
  7. cout << "value 容量是:" << value.capacity() << endl;
  8. cout << "value 大小是:" << value.size() << endl;
  9. printf("value首地址:%p\n", value.data());
  10. value.push_back(53);
  11. cout << "value 容量是(2):" << value.capacity() << endl;
  12. cout << "value 大小是(2):" << value.size() << endl;
  13. printf("value首地址: %p", value.data());
  14. return 0;
  15. }

运行结果为:

value 容量是:15
value 大小是:15
value首地址:01254D40
value 容量是(2):22
value 大小是(2):16
value首地址: 01254E80

可以看到,向“已满”的 vector 容器再添加一个元素,整个 value 容器的存储位置发生了改变,同时 vector 会一次性申请多个存储空间(具体多少,取决于底层算法的实现)。这样做的好处是,可以很大程度上减少 vector 申请空间的次数,当后续再添加元素时,就可以节省申请空间耗费的时间。

因此,对于 vector 容器而言,当增加新的元素时,有可能很快完成(即直接存在预留空间中);也有可能会慢一些(扩容之后再放新元素)。

修改vector容器的容量和大小

另外,通过前面的学习我们知道,可以调用 reserve() 成员函数来增加容器的容量(但并不会改变存储元素的个数);而通过调用成员函数 resize() 可以改变容器的大小,并且该函数也可能会导致 vector 容器容量的增加。比如说:

  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4. int main()
  5. {
  6. vector<int>value{ 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47 };
  7. cout << "value 容量是:" << value.capacity() << endl;
  8. cout << "value 大小是:" << value.size() << endl;
  9. value.reserve(20);
  10. cout << "value 容量是(2):" << value.capacity() << endl;
  11. cout << "value 大小是(2):" << value.size() << endl;
  12. //将元素个数改变为 21 个,所以会增加 6 个默认初始化的元素
  13. value.resize(21);
  14. //将元素个数改变为 21 个,新增加的 6 个元素默认值为 99。
  15. //value.resize(21,99);
  16. //当需要减小容器的大小时,会移除多余的元素。
  17. //value.resize(20);
  18. cout << "value 容量是(3):" << value.capacity() << endl;
  19. cout << "value 大小是(3):" << value.size() << endl;
  20. return 0;
  21. }

运行结果为:

value 容量是:15
value 大小是:15
value 容量是(2):20
value 大小是(2):15
value 容量是(3):30
value 大小是(3):21

程序中给出了关于 resize() 成员函数的 3 种不同的用法,有兴趣的读者可自行查看不同用法的运行结果。

可以看到,仅通过 reserve() 成员函数增加 value 容器的容量,其大小并没有改变;但通过 resize() 成员函数改变 value 容器的大小,它的容量可能会发生改变。另外需要注意的是,通过 resize() 成员函数减少容器的大小(多余的元素会直接被删除),不会影响容器的容量。

vector容器容量和大小的数据类型

在实际场景中,我们可能需要将容器的容量和大小保存在变量中,要知道 vector<T> 对象的容量和大小类型都是 vector<T>::size_type 类型。因此,当定义一个变量去保存这些值时,可以如下所示:

  1. vector<int>::size_type cap = value.capacity();
  2. vector<int>::size_type size = value.size();

size_type 类型是定义在由 vector 类模板生成的 vecotr 类中的,它表示的真实类型和操作系统有关,在 32 位架构下普遍表示的是 unsigned int 类型,而在 64 位架构下普通表示 unsigned long 类型。

当然,我们还可以使用 auto 关键字代替 vector<int>::size_type,比如:

  1. auto cap = value.capacity();
  2. auto size = value.size();

C++ STL vector容量(capacity)和大小(size)的区别的更多相关文章

  1. C++STL——vector类

    vector容器 1.1 vector容器的基本概念 Array 是静态空间,一旦配置了就不能改变,要换大一点或者小一 点的空间,可以,一切琐碎得由自己来,首先配置一块新的空间,然后将旧空间的 数据搬 ...

  2. C++ STL vector(向量容器)的使用(附完整程序代码)

    一.简单介绍 Vectors 包括着一系列连续存储的元素,其行为和数组类似. 訪问Vector中的随意元素或从末尾加入元素都能够在O(1)内完毕,而查找特定值的元素所处的位置或是在Vector中插入元 ...

  3. STL—Vector简介

    有关C++ STL 中的vector向量的用法(代码示例) 一. 简介 Vector是一个称为向量的顺序容器(不明白顺序容器与关联容器的可以Google). 二. 特点 1. 动态(相当于一个动态数组 ...

  4. STL vector用法介绍

    STL vector用法介绍 介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和f ...

  5. C++ STL vector 内存分配

    vector为了支持快速的随机访问,vector容器的元素以连续方式存放,每一个元素都紧挨着前一个元素存储. 当vector添加一个元素时,为了满足连续存放这个特性,都需要重新分配空间.拷贝元素.撤销 ...

  6. STL vector 用法介绍

    介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和for_each()中的使用.通 ...

  7. STL vector使用方法介绍

    介绍 这篇文章的目的是为了介绍std::vector,怎样恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和for_each()中的使用.通 ...

  8. stl——vector详解

    stl——vector详解 stl——vector是应用最广泛的一种容器,类似于array,都将数据存储于连续空间中,支持随机访问.相对于array,vector对空间应用十分方便.高效,迭代器使ve ...

  9. C++STL vector详解(杂谈)

    介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和for_each()中的使用.通 ...

随机推荐

  1. SpringBoot-自动装载

    1,SpringBoot里面有内置的tomcat容器. 2,SpringBoot是基于已有的东西创建的新的东西.核心:(AutoConfiguration)自动装载,Starter,Actuator, ...

  2. Flutter Android 真机器调试 、模拟器调试、Vscode 中开发 Flutter 应用

    必备条件: 1.准备一台 Android 手机 2.手机需要开启调试模式 3.用数据线把手机连上电脑 4.手机要允许电脑进行 Usb 调试 5.手机对应的 sdk 版本必须安装 注意: 1.关闭电脑上 ...

  3. bfs迷宫

    链接:https://ac.nowcoder.com/acm/contest/338/BSleeping is a favorite of little bearBaby, because the w ...

  4. 【PAT甲级】1100 Mars Numbers (20 分)

    题意: 输入一个正整数N(<100),接着输入N组数据每组包括一行字符串,将其翻译为另一个星球的数字. AAAAAccepted code: #define HAVE_STRUCT_TIMESP ...

  5. iOS开发常用Mac终端命令

    常用命令: 1.grep -lr "prefs:root=" * cd 当某一文件夹下,在当前文件目录下搜索对应的内容(橘色字符串替换为你想要搜索的内容).可以用来搜索工程中在第三 ...

  6. C/C++中size_t潜在的问题

    在C++中,利用数组下标访问数组元素时,常常将下标类型定义为size_t类型,因为正常来说,数组的下标就是size_t类型.例如这样: for (size_t i = 0; i < contai ...

  7. phpRedis函数使用总结【分类详细】

    <?php /*1.Connection*/ $redis = new Redis(); $redis->connect('127.0.0.1',6379,1);//短链接,本地host, ...

  8. C# 动态类型 以及 脚本调用(scriptRunTime)

    在使用中让我感觉 好像 JavaScript中的 动态类型囧 先看动态类型 class Program { static void Main(string[] args) { var streamRe ...

  9. PHP将json或对象转成数组

    今天老大突然给了我一个小任务,给我一个txt文件,里边是很多的json字串,要求将这些字串转换成php中的数组: 于是开足火力,用了将进5分钟的时间完成了任务,代码如下: $jsonStr = fil ...

  10. hexo 搭建静态博客 + Next 主题配置

    参考手册 HEXO:https://hexo.io/zh-cn/ NEXT:http://theme-next.iissnan.com/ 安装hexo npm install hexo-cli -g ...