// string::shrink_to_fit
#include <iostream>
#include <string>

int main ()
{
std::string str (100,'x');
std::cout << "1. capacity of str: " << str.capacity() << '\n';

str.resize(10);
std::cout << "2. capacity of str: " << str.capacity() << '\n';

str.shrink_to_fit();
std::cout << "3. capacity of str: " << str.capacity() << '\n';

return 0;
}

1. capacity of str: 100

2. capacity of str: 100

3. capacity of str: 10

上述代码实现了以下功能

#include <iostream>
using namespace std;

int main()
{
vector<int>vec;
for(int i = 0 ;i < 100 ; ++i)
vec.push_back(i);

cout << vec.size() << endl; //100
cout << vec.capacity() << endl; //128

vec.erase(vec.begin()+10,vec.end()); //改变了size,但是并未改变capccity
cout << vec.size() << endl; //10
cout << vec.capacity() << endl; //128

vector<int>(vec).swap(vec);
cout << vec.size() << endl; //10
cout << vec.capacity() << endl; //10

vec.clear(); //clear并未真正释放空间!!!
cout << vec.size() << endl; //0
cout << vec.capacity() << endl; //10

vector<int> (vec).swap(vec); //这才真正释放了空间!!
cout << vec.size() << endl; //0
cout << vec.capacity() << endl; //0
return 0;
}

shrink_to_fit才是设计来替代swap释放内存的问题的。应该尽量用shrink_to_fit
shrink_to_fit会在几种典型情况下放弃重分配:
元素类型不支持无异常移动。使用拷贝完成内存重分配期间某个元素构造抛出异常。此时函数回滚容器到调用前状态,错误不返回。
重分配新位置需要的内存失败。
capacity()和size()相等(这种是典型情况,表示不需要重分配)。
 

放弃重分配,就是说恢复到shrink_to_fit调用以前的状态,表现的就好像这个函数根本没调用过。
构造函数表示错误状态只能通过抛异常来实现,因为构造函数没有返回值,在内层函数构造的时候一般也没有办法向通过返回值的方法向外层返回错误。至于抛不抛异常、什么时候会抛,要看元素类是怎么设计的。
回滚就是说,比如一个vector之类的容器,里面已经有10个元素,而capacity()为11,这时候调用shrink_to_fit,这个函数先分配了新的内存块刚好能容纳10个元素;接下来逐一将元素从旧的地址构造到这个新内存块的对应位置。而因为元素类不支持无异常的移动构造而使vector决定用拷贝构造的方式构造新元素。然后,比如当拷贝第4个元素的时候元素构造函数抛出异常,这时候该怎么办?vector接下来会把刚才构造成功的3个元素析构掉,然后删除新分配的那块内存后从shrink_to_fit返回。这样vector的capacity()仍旧是11而原来的10个元素都继续保持有效。这就跟没调用过shrink_to_fit一样

shrink_to_fit的更多相关文章

  1. c++ 将容量设置为容器的长度(shrink_to_fit)

    #include <iostream> #include <vector> using namespace std; int main () { vector<); co ...

  2. 实战c++中的vector系列--正确释放vector的内存(clear(), swap(), shrink_to_fit())

    关于vector已经写的差不多了,似乎要接近尾声了,从初始化到如何添加元素再到copy元素都有所涉及,是时候谈一谈内存的释放了. 是的,对于数据量很小的vector,完全没必要自己进行主动的释放,因为 ...

  3. Vector shrink 请求容器降低其容量和size匹配 shrink_to_fit();

    一.先从size 和capacity 说起 resize(),设置大小(size); reserve(),设置容量(capacity); size()是分配容器的内存大小,而capacity()只是设 ...

  4. c++ Size capacity Resize reserve shrink_to_fit

  5. EasyPR--开发详解(8)文字定位

    今天我们来介绍车牌定位中的一种新方法--文字定位方法(MSER),包括其主要设计思想与实现.接着我们会介绍一下EasyPR v1.5-beta版本中带来的几项改动. 一. 文字定位法 在EasyPR前 ...

  6. C++ std::deque

    std::deque template < class T, class Alloc = allocator > class deque; Double ended queue deque ...

  7. c++ vector 使用

    1. 包含一个头文件: 1 #include <vector> 2. 申明及初始化: std::vector<int> first; // empty vector of in ...

  8. C++ STL之vector用法总结

    介绍 vector是表示可变大小数组的序列容器. 就像数组一样,vector也采用的连续存储空间来存储元素.也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效.但是又不像数组,它的大 ...

  9. Ptex源码学习笔记-2

    写入纹理数据: 主要分为五种写入方式:新建纹理.编辑已有纹理.编辑ExtHeader中的指定项.写入元数据和写入指定面的纹理数据.写入过程中数据存在一个临时文件中,在close时才会把临时文件的内容拷 ...

随机推荐

  1. 『Pandas』数据读取&DataFrame切片

    读取文件 numpy.loadtxt() import numpy as np dataset_filename = "affinity_dataset.txt" X = np.l ...

  2. python-day20--collections模块

    1.namedtuple: 生成可以使用名字来访问元素内容的tuple >>> from collections import namedtuple >>> Poi ...

  3. CNN autoencoder 进行异常检测——TODO,使用keras进行测试

    https://sefiks.com/2018/03/23/convolutional-autoencoder-clustering-images-with-neural-networks/ http ...

  4. Python学习之路day3-集合

    一.概述 集合(set)是一种无序且不重复的序列. 无序不重复的特点决定它存在以下的应用场景: 去重处理 关系测试 差集.并集.交集等,下文详述. 二.创建集合 创建集合的方法与创建字典类似,但没有键 ...

  5. elment-ui table组件 -- 远程筛选排序

    elment-ui table组件 -- 远程筛选排序 基于 elment-ui table组件 开发,主要请求后台实现筛选 排序的功能. 需求 排序 筛选 是对后台整个数据进行操作,而不是对当前页面 ...

  6. 新手也能学会本地调试微信,natapp 官网映射

    本地调试微信的新手指引~ 照着配置,一定可以配置成功,实现本地调试微信,公司好几个同事按照我写的步骤,都独立配成功了. 1.首选在natapp注册一个账号,申请免费隧道或者购买隧道,我买了一个月9元的 ...

  7. 猎豹浏览器(chrome内核)屏蔽视频广告

    1.基于猎豹浏览器(原则上chrome内核浏览器都可以) 2.下载插件Adblock Plus,下载地址:http://chromecj.com/productivity/2014-07/24/dow ...

  8. Oracle 与Sql Server常用函数对比

    来自:http://topic.csdn.net/u/20080704/08/b2b8c42f-b0d6-4cda-98b1-6e4a279b4ff8.html 感谢楼主 函数 SQLServer和O ...

  9. delete p和delete [] p的区别(转)

    operator new 和 operator delete函数有两个重载版本,每个版本支持相关的new表达式和delete表达式: void* operator new (size_t); // a ...

  10. Delphi发布了社区版及Delphi 10.3展望

    http://altd.embarcadero.com/download/radstudio/10.2/delphicbuilder10_2_3__93231.iso,注册机在这里 注册号要自己去申请 ...