面试被问到如何解决 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),它会将 vectorother 相交换,且不在单独的元素上调用任何移动、复制或交换操作。利用 swap() 释放多余的存储空间的操作如下:

vector<int>(vec).swap(vec);

表达式 vector<int>(vec) 建立一个临时 vector,它是 vec 的一份拷贝,vector 的复制构造函数做了这个工作。并且,这个复制品只复制了复制元素所需要的内存,所以这个临时 vector 没有多余的容量。

然后,让临时 vectorvec 交换数据,vec 拥有了临时 vector 的修整过的容量,而临时 vector 则拥有了发胀的容量。最后语句执行完毕,临时 vector 被析构,空间被释放,大功告成。

vector 的交换技巧的更多相关文章

  1. SEO-关键词密度与友情链接交换技巧

    关键词密度 关键词密度 关键词密度与关键词频率所阐述的实质上是同一个概念,用来量度关键词在网页上出现的总次数与其他文字的比例,一般用百分比表示.相对于页面总字数而言,关键词出现的频率越高,关键词密度也 ...

  2. 动态表和C++ vector

    动态表和C++ vector 最近课上刚刚学了可以根据表中元素的插入和删除动态调整表大小的动态表(dynamic table),就想看一下它有什么实际的应用,第一个想起来的就是C++的vector,直 ...

  3. c++中vector的用法详解

    c++中vector的用法详解 vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间 ...

  4. C++中 vector(容器)的用法

    vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间的目的. 用法: 1.文件包含: ...

  5. C++中vector的用法

    C++内置的数组支持容器的机制,但是它不支持容器抽象的语义.要解决此问题我们自己实现这样的类.在标准C++中,用容器向量(vector)实现.容器向量也是一个类模板.标准库vector类型使用需要的头 ...

  6. vector容器的用法

    转自一篇博客^-^: 1 基本操作 (1)头文件#include<vector>. (2)创建vector对象,vector<int> vec; (3)尾部插入数字:vec.p ...

  7. c++ 的vector

    使用例子:std::vector<std::string> xmlNodeList; 下面介绍-- vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组 ...

  8. vector 的resize 和 reserve

    首先声明,都是转载的,理解知识为主要目的. http://www.cnblogs.com/zahxz/archive/2013/02/20/2918711.html C++内置的数组支持容器的机制,但 ...

  9. vector 释放内存 swap

    相 信大家看到swap这个词都一定不会感到陌生,甚至会有这样想法:这不就是简单的元素交换嘛.的确,swap交换函数是仅次于Hello word这样老得不能老的词,然而,泛型算法东风,这个小小的玩意儿却 ...

随机推荐

  1. 【转】java内存溢出的场景及解决办法

    参考: https://blog.csdn.net/qq_32671287/article/details/86063396 https://www.cnblogs.com/snowwhite/p/9 ...

  2. 【springcloud】Zuul 超时、重试、并发参数设置

    转自:https://blog.csdn.net/xx326664162/article/details/83625104 一. Zuul 服务网关 服务网关 = 路由转发 + 过滤器 1.路由转发: ...

  3. springcloud starter(一)

    Spring Cloud - Getting Started Example, 转载自:https://www.logicbig.com/tutorials/spring-framework/spri ...

  4. SpringCloud升级之路2020.0.x版-24.测试Spring Cloud LoadBalancer

    本系列代码地址:https://github.com/HashZhang/spring-cloud-scaffold/tree/master/spring-cloud-iiford 通过单元测试,我们 ...

  5. 温故知新:老铁,WeakReference了解一下?

    本文供稿--大师兄 弱引用是个什么鬼?大白话说就是不那么强的引用(哈哈,纯属玩笑,实际可不是这样滴),那强引用又是个什么鬼?他们有什么用处?问题有点迷,君阅完这篇文章后或许你心中就有答案了-- 什么是 ...

  6. 面试必备:排序算法汇总(c++实现)

    排序算法主要考点: 7种排序 冒泡排序.选择排序.插入排序.shell排序.堆排序.快速排序.归并排序 以上排序算法是面试官经常会问到的算法,至于其他排序比如基数排序等等,这里不列举. 以下算法通过c ...

  7. 基于Linux系统下Apache服务器的安装部署

    企业中常用的web服务,用来提供http://(超文本传输协议). web系统是客户端/服务器模式的,所以应该有服务器和客户端里两个部分.常用的服务器程序时Apache,常用的客户端程序是浏览器.ww ...

  8. Python面向对象编程及内置方法

    在程序开发中,要设计一个类,通常需要满足以下三个要求: [1]类名 这类事物的名字,满足大驼峰命名法 [2]属性 这类事物具有什么样的特征 [3]方法 这类事物具有什么样的行为 定义简单的类: 定义只 ...

  9. Python之requests模块-cookie

    cookie并不陌生,与session一样,能够让http请求前后保持状态.与session不同之处,在于cookie数据仅保存于客户端.requests也提供了相应到方法去处理cookie. 在py ...

  10. (二)Superset 1.3图表篇——Time-series Table

    (二)Superset 1.3图表篇--Time-series Table 本系列文章基于Superset 1.3.0版本.1.3.0版本目前支持分布,趋势,地理等等类型共59张图表.本次1.3版本的 ...