C++ vector swap()去除多余容量

2024-04-12 02:18

本文主要是介绍C++ vector swap()去除多余容量,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

今天在查询swap()函数的时候,发现了swap()函数居然可以用来减少vector容器的大小,

众所周知,vector的容器的大小只可以增加,不可以减少。当我们使用push_back(),insert(),emplace()

等成员方法的时候,有可能会增加容量,但是我们使用 pop_back()、erase()、clear() 等方式的时候,并不会减少实际 的内存容量。只是可以删除容器里面的内容。

 
  1. #include <iostream>

  2. #include <vector>

  3. using namespace std;

  4.  
  5. int main()

  6. {

  7. vector<int>myvector;

  8. cout << "1、当前 myvector 拥有 " << myvector.size() << " 个元素,容量为 " << myvector.capacity() << endl;

  9. //利用 myvector 容器存储 10 个元素

  10. for (int i = 1; i <= 10; i++) {

  11. myvector.push_back(i);

  12. }

  13. cout << "2、当前 myvector 拥有 " << myvector.size() << " 个元素,容量为 " << myvector.capacity() << endl;

  14. //手动为 myvector 扩容

  15. myvector.reserve(1000);

  16. cout << "3、当前 myvector 拥有 " << myvector.size() << " 个元素,容量为 " << myvector.capacity() << endl;

  17. myvector.erase(myvector.begin());

  18. cout << "4、当前 myvector 拥有 " << myvector.size() << " 个元素,容量为 " << myvector.capacity() << endl;

  19.  
  20. myvector.pop_back();

  21. cout << "5、当前 myvector 拥有 " << myvector.size() << " 个元素,容量为 " << myvector.capacity() << endl;

  22.  
  23. myvector.clear();

  24. cout << "6、当前 myvector 拥有 " << myvector.size() << " 个元素,容量为 " << myvector.capacity() << endl;

  25. return 0;

  26. }

结果为:

1、当前 myvector 拥有 0 个元素,容量为 0
2、当前 myvector 拥有 10 个元素,容量为 13
3、当前 myvector 拥有 10 个元素,容量为 1000

4、当前 myvector 拥有 9 个元素,容量为 1000
5、当前 myvector 拥有 8 个元素,容量为 1000
6、当前 myvector 拥有 0 个元素,容量为 1000

显然,myvector 容器存储的元素个数在减少,但容量并不会减小。

幸运的是,myvector 模板类中提供有一个 shrink_to_fit() 成员方法,该方法的功能是将当前 vector 容器的容量缩减至和实际存储元素的个数相等。例如,在程序一的基础上,添加如下语句:

 
  1. myvector.shrink_to_fit();

  2. cout << "7、当前 myvector 拥有 " << myvector.size() << " 个元素,容量为 " << myvector.capacity() << endl;

7、当前 myvector 拥有 10 个元素,容量为 10

除此之外,可以利用swap()方法进行出去vector多余的容量,

swap()的原型

 
  1. template <class T> void swap (T& a, T& b)

  2. {

  3. T c(std::move(a)); a=std::move(b); b=std::move(c);

  4. }

  5. template <class T, size_t N> void swap (T &a[N], T &b[N])

  6. {

  7. for (size_t i = 0; i<N; ++i) swap (a[i],b[i]);

  8. }

所以,swap()函数,本质是进行右值移动。

所以,想要用swap()进行去除多余的容量是,这么回事勒?

vector<T>(x).swap(x);

期中,x是当前要操作的容器,T是容器的类型。

 
  1. #include <iostream>

  2. #include <vector>

  3. using namespace std;

  4.  
  5. int main()

  6. {

  7. vector<int>myvector;

  8. //手动为 myvector 扩容

  9. myvector.reserve(1000);

  10. cout << "1、当前 myvector 拥有 " << myvector.size() << " 个元素,容量为 " << myvector.capacity() << endl;

  11. //利用 myvector 容器存储 10 个元素

  12. for (int i = 1; i <= 10; i++) {

  13. myvector.push_back(i);

  14. }

  15. //将 myvector 容量缩减至 10

  16. vector<int>(myvector).swap(myvector);

  17. cout << "2、当前 myvector 拥有 " << myvector.size() << " 个元素,容量为 " << myvector.capacity() << endl;

  18. return 0;

  19. }

程序的结果为:

1、当前 myvector 拥有 0 个元素,容量为 1000
2、当前 myvector 拥有 10 个元素,容量为 10

这个代码可以分成3部走,

(1)先执行 vector<int>(myvector),此表达式会调用 vector 模板类中的拷贝构造函数,从而创建出一个临时的 vector 容器(后续称其为 tempvector)。值得一提的是,tempvector 临时容器并不为空,因为我们将 myvector 作为参数传递给了复制构造函数,该函数会将 myvector 容器中的所有元素拷贝一份,并存储到 tempvector 临时容器中。但是,vector 模板类中的拷贝构造函数只会为拷贝的元素分配存储空间。换句话说,tempvector 临时容器中没有空闲的存储空间,其容量等于存储元素的个数

(2)然后借助 swap() 成员方法对 tempvector 临时容器和 myvector 容器进行调换,此过程不仅会交换 2 个容器存储的元素,还会交换它们的容量。换句话说经过 swap() 操作,myvetor 容器具有了 tempvector 临时容器存储的所有元素和容量,同时 tempvector 也具有了原 myvector 容器存储的所有元素和容量。

(3) 当整条语句执行结束时,临时的 tempvector 容器会被销毁,其占据的存储空间都会被释放。注意,这里释放的其实是原 myvector 容器占用的存储空间。

利用swap()方法清空vector容器

当 swap() 成员方法用于清空 vector 容器时,可以套用如下的语法格式:

vector<T>().swap(x);

       和上面语法格式唯一的不同之处在于,这里没有为 vector<T>() 表达式传递任何参数。这意味着,此表达式将调用 vector 模板类的默认构造函数,而不再是复制构造函数。也就是说,此格式会先生成一个空的 vector 容器,再借助 swap() 方法将空容器交换给 x,从而达到清空 x 的目的。

https://blog.csdn.net/id145/article/details/108304537

这篇关于C++ vector swap()去除多余容量的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/895834

相关文章

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

C++ STL-string类底层实现过程

《C++STL-string类底层实现过程》本文实现了一个简易的string类,涵盖动态数组存储、深拷贝机制、迭代器支持、容量调整、字符串修改、运算符重载等功能,模拟标准string核心特性,重点强... 目录实现框架一、默认成员函数1.默认构造函数2.构造函数3.拷贝构造函数(重点)4.赋值运算符重载函数

C++ vector越界问题的完整解决方案

《C++vector越界问题的完整解决方案》在C++开发中,std::vector作为最常用的动态数组容器,其便捷性与性能优势使其成为处理可变长度数据的首选,然而,数组越界访问始终是威胁程序稳定性的... 目录引言一、vector越界的底层原理与危害1.1 越界访问的本质原因1.2 越界访问的实际危害二、基

c++日志库log4cplus快速入门小结

《c++日志库log4cplus快速入门小结》文章浏览阅读1.1w次,点赞9次,收藏44次。本文介绍Log4cplus,一种适用于C++的线程安全日志记录API,提供灵活的日志管理和配置控制。文章涵盖... 目录简介日志等级配置文件使用关于初始化使用示例总结参考资料简介log4j 用于Java,log4c

C++归并排序代码实现示例代码

《C++归并排序代码实现示例代码》归并排序将待排序数组分成两个子数组,分别对这两个子数组进行排序,然后将排序好的子数组合并,得到排序后的数组,:本文主要介绍C++归并排序代码实现的相关资料,需要的... 目录1 算法核心思想2 代码实现3 算法时间复杂度1 算法核心思想归并排序是一种高效的排序方式,需要用

浅谈MySQL的容量规划

《浅谈MySQL的容量规划》进行MySQL的容量规划是确保数据库能够在当前和未来的负载下顺利运行的重要步骤,容量规划包括评估当前资源使用情况、预测未来增长、调整配置和硬件资源等,感兴趣的可以了解一下... 目录一、评估当前资源使用情况1.1 磁盘空间使用1.2 内存使用1.3 CPU使用1.4 网络带宽二、

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

C++中detach的作用、使用场景及注意事项

《C++中detach的作用、使用场景及注意事项》关于C++中的detach,它主要涉及多线程编程中的线程管理,理解detach的作用、使用场景以及注意事项,对于写出高效、安全的多线程程序至关重要,下... 目录一、什么是join()?它的作用是什么?类比一下:二、join()的作用总结三、join()怎么