vector 的交换技巧
面试被问到如何解决 vector 有过多空闲内存的问题。
假定先有一 vector 容器 vec,它的容量是 10000,大小是 3。
vector 的内存增长问题
vector 申请的是连续内存空间,其实际分配的内存比当前所需的内存要多一些,也就是说,vector 容器预留了一些额外的存储区。而当 vector 需要分配新的内存时,会申请当前容量二倍的内存,也就是二倍增长。
resize() 和 reverse()
resize() 并不能解决内存浪费的问题。使用 resize() 可以将一个容量和大小均为 10000 的 vector 的大小改为 3,但 resize() 并不是将其余的内存释放掉,后面的内存仍然被占用,因为此时 vector 的容量(capacity())仍为 10000。
这时候想到,要是先用 resize() 减小容器的大小,再使用 reverse() 减少容器的容量,不就好了么?但这样也不行,当使用 reverse() 调整容器容量时,若 new_cap 大于当前 capacity(),则会分配新的存储空间,复制原容器元素,销毁原容器;但若 new_cap 小于当前 capacity(),则什么也不做。
例如以下代码:
#include <iomanip>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
// 初始化时预算分配 10000 的大小.
vector<int> vec(10000, 1);
cout << setiosflags(ios::left);
cout << "Initial\n"
<< setw(20) << "vec's size(): " << vec.size() << endl
<< setw(20) << "vec's capacity(): " << vec.capacity() << endl
<< endl;
// 调整容器大小. 假定现在只需要 3 的大小.
vec.resize(3);
cout << "After resize()\n"
<< setw(20) << "vec's size(): " << vec.size() << endl
<< setw(20) << "vec's capacity(): " << vec.capacity() << endl
<< endl;
// 调整容器容量.
vec.reserve(3);
cout << "After reserve()\n"
<< setw(20) << "vec's size(): " << vec.size() << endl
<< setw(20) << "vec's capacity(): " << vec.capacity() << endl
<< endl;
return 0;
}
输出为:
Initial
vec's size(): 10000
vec's capacity(): 10000
After resize()
vec's size(): 3
vec's capacity(): 10000
After reserve()
vec's size(): 3
vec's capacity(): 10000
可以看到 resize() 和 reverse() 无法处理浪费的空间。
交换技巧
交换技巧,使用到了 swap(vector& other),它会将 vector 与 other 相交换,且不在单独的元素上调用任何移动、复制或交换操作。利用 swap() 释放多余的存储空间的操作如下:
vector<int>(vec).swap(vec);
表达式 vector<int>(vec) 建立一个临时 vector,它是 vec 的一份拷贝,vector 的复制构造函数做了这个工作。并且,这个复制品只复制了复制元素所需要的内存,所以这个临时 vector 没有多余的容量。
然后,让临时 vector 和 vec 交换数据,vec 拥有了临时 vector 的修整过的容量,而临时 vector 则拥有了发胀的容量。最后语句执行完毕,临时 vector 被析构,空间被释放,大功告成。
vector 的交换技巧的更多相关文章
- SEO-关键词密度与友情链接交换技巧
关键词密度 关键词密度 关键词密度与关键词频率所阐述的实质上是同一个概念,用来量度关键词在网页上出现的总次数与其他文字的比例,一般用百分比表示.相对于页面总字数而言,关键词出现的频率越高,关键词密度也 ...
- 动态表和C++ vector
动态表和C++ vector 最近课上刚刚学了可以根据表中元素的插入和删除动态调整表大小的动态表(dynamic table),就想看一下它有什么实际的应用,第一个想起来的就是C++的vector,直 ...
- c++中vector的用法详解
c++中vector的用法详解 vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间 ...
- C++中 vector(容器)的用法
vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间的目的. 用法: 1.文件包含: ...
- C++中vector的用法
C++内置的数组支持容器的机制,但是它不支持容器抽象的语义.要解决此问题我们自己实现这样的类.在标准C++中,用容器向量(vector)实现.容器向量也是一个类模板.标准库vector类型使用需要的头 ...
- vector容器的用法
转自一篇博客^-^: 1 基本操作 (1)头文件#include<vector>. (2)创建vector对象,vector<int> vec; (3)尾部插入数字:vec.p ...
- c++ 的vector
使用例子:std::vector<std::string> xmlNodeList; 下面介绍-- vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组 ...
- vector 的resize 和 reserve
首先声明,都是转载的,理解知识为主要目的. http://www.cnblogs.com/zahxz/archive/2013/02/20/2918711.html C++内置的数组支持容器的机制,但 ...
- vector 释放内存 swap
相 信大家看到swap这个词都一定不会感到陌生,甚至会有这样想法:这不就是简单的元素交换嘛.的确,swap交换函数是仅次于Hello word这样老得不能老的词,然而,泛型算法东风,这个小小的玩意儿却 ...
随机推荐
- jsoup的Element类
一.简介 该类是Node的直接子类,同样实现了可克隆接口.类声明:public class Element extends Node 它表示由一个标签名,多个属性和子节点组成的html元素.从这个元素 ...
- redis 《scan命令》
此命令十分奇特建议参考文档:http://redisdoc.com/database/scan.html#scan 222222222222222并非每次迭代都要使用相同的 COUNT 值. ...
- 性能测试工具JMeter 基础(九)—— 测试元件: 逻辑控制器之交替控制器
交替控制器:根据被控制器触发执行次数,去依次执行控制器下的子节点(逻辑控制器.采样器),可以由线程组的线程数.循环次数.逻辑控制器触发. 交替控制器(lnterleave Controller) 简单 ...
- JS_DOM操作之常用事件
1 - onload 事件:加载完成后立即执行 <!DOCTYPE html> <html lang="en"> <head> <meta ...
- python获取邮件信息
在项目的Terminal中注册模块pypiwin32 python -m pip install pypiwin32 import win32com.client outlook = win32com ...
- Vite详解
vite 目录 一.推荐两个插件插件 Volar Vue 3 Snippets 二.vite简介 优势分析 浏览器支持 三.vite搭建vue3.x项目 1.创建项目 2.集成Vue-Router 3 ...
- vue 动态ip配置,避免重复打包
目前比较流行的打包大都是在vue.config.js配置代理,然后在根目录新建.env.xxx文件配置正式环境,测试环境,开发环境等用于打包时配置不同的访问地址,作为一名随波逐流的前端开发,我也是这么 ...
- leetcode 盛水最多的容器 解析
采用双指针法: 主要思想:定义头尾两个指针,分别向中间遍历,当相遇时结束循环.存储每一次遍历容器盛水的最大容量,并不断更新. 盛水的最大容量为 左右指针高度的最小值 乘以 左右指针的距离即宽度. 则可 ...
- PHP获取当前网址路径
$_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'] // 获取来源 function ...
- 怎样在Linux中查看apache是用那个httpd.conf
第一步:找到apache启动命令: [root@WAPBJ01 ~]# ps -ef|grep httpdroot 10575 1 0 19:45 ? 00:00:03 ...