// 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. STL_string

    将string对象利用c风格的形式输出函数:  c_str() 栗子:      string s;      printf("%s\n",s.c_str());

  2. 访问IIS元数据库失败的解决方法

    这两天在调试一个Asp.net程序时,出现了“访问IIS元数据库失败”的错误信息,最后终于摸索出了解决问题的方法.公布如下: 1.依次点击“开始”-“运行”. 2.在“运行”栏内输入 “C:\WIND ...

  3. en_a

      1◆ai ay ei     2◆ au aw ɔː     3◆ a   eɪ æ ɑː ɔː ʌ   4◆ ar   ɔː ɑː ɜː   5◆ al ɑː ɔː   6◆ are air   ...

  4. 062——VUE中vue-router之命名视图的实例

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. linux pipes

    In Linux, a pipe is implemented using two filedata structures which both point at the same temporary ...

  6. myeclipse设置jvm参数的三种方式

    方法一: 打开eclipse,选择Window--Preferences...在对话框左边的树上双击Java,再双击Installed JREs,在右边选择前面有对勾的JRE,再单击右边的“Edit” ...

  7. pl/sql快速输入select等语句

    平时对数据库操作的时候,输入DML语句,很浪费时间,我们想要这样的效果 ,输入sf,plsql就会自动输入select * from.我们需要在plsql中进行如下设置即可: 工具(tools)--& ...

  8. Programming Contest Ranking(题解)

    Programming Contest Ranking . 题目描述 Heilongjiang Programming Contest will end successfully! And your ...

  9. 会话跟踪session

    会话跟踪 HTTP是“无状态”协议:客户程序每次读取Web页面,都打开到web服务器的单独的连接,而且,服务器也不自动维护客户的上下文信息.类似客户决定结账时,如何确定之前创建的购物车中哪个属于此客户 ...

  10. 关于LUN和卷的思考

    LUN:logical unit number 是指硬件层分出的逻辑盘,OS仍然把这些逻辑盘看成是物理盘. 例如将一个1PB磁盘柜划分为100个相同大小的lun,那么每个lun的大小就是10TB,lu ...