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这样老得不能老的词,然而,泛型算法东风,这个小小的玩意儿却 ...
随机推荐
- 【linux】vim常用命令
转自:https://www.runoob.com/linux/linux-vim.html vi/vim 的使用 基本上 vi/vim 共分为三种模式,分别是命令模式(Command mode),输 ...
- MyBatis like报错
错误的likeSQL语句是这么写的 select * from student name like '%#{name}%' 下面是错误信息 Parameter index out of range ( ...
- Hexo搭建个人静态博客网站
前言 前段时间博客园整改,许多博客无法查看,偶然的机会接触到了许多博客框架,可用来快速搭建一个静态博客网站:最后选择使用hexo,看了不少大佬的教程,觉得挺有意思的,于是也总结了一下自己的搭建步骤,可 ...
- redhat9 linux 网卡无法激活排障
先查看自己的系统版本! [root@localhost root]# uname -a Linux localhost 2.4.20-8 #1 Thu Mar 13 17:54:28 EST 2003 ...
- BUUCTF-[CISCN2019 华北赛区 Day1 Web5]CyberPunk
BUUCTF-[CISCN2019 华北赛区 Day1 Web5]CyberPunk 看题 看源码有提示?file=? 文件包含漏洞,可以利用这个漏洞读取源码. 分析 index.php?file=p ...
- uni-app 入门小白纯徒手编写组件 hello-popup
我的需求是:弹出框顶部有 title,底部有确认和取消按钮.这两部分固定,中间部分 content 的高度随自身内容会动态增长,但是它最大高度不能超过父节点 bg 的 80%,而父节点 bg 的高度也 ...
- 爱思助手备份 iPhone 时没有设置密码,恢复备份时需要密码的问题
i4.cn 备份时 iPhone 上登陆的 Apple ID 曾经设置过备份密码,这个密码就是恢复备份时需要输入的密码!
- GoLang设计模式04 - 单例模式
单例模式恐怕是最为人熟知的一种设计模式了.它同样也是创建型模式的一种.当某个struct只允许有一个实例的时候,我们会用到这种设计模式.这个struct的唯一的实例被称为单例对象.下面是需要创建单例对 ...
- C# Dapper基本三层架构使用 (二、Model)
我们将数据存放在数据库中,数据表的结构,我们通常会用一个类来抽象,表的属性就是类的属性,我们通常将表的一行存储在一个类中. 在Java中,通常将其称为实体类Entity,在C#中,通常将其称为Mode ...
- CSS滤镜让图片模糊(毛玻璃效果)
CSS代码: .blur { filter: url(blur.svg#blur); /* FireFox, Chrome, Opera */ -webkit-filter: blur(10px); ...