1.vector元素的清除

看代码。在vector中添加若干元素,然后clear()

 #include<iostream>
#include<list>
#include<vector>
#include<iterator>
#include<string>
using std::vector;
using std::list;
using std::iterator;
using std::string;
using std::cout;
using std::endl; int main()
{
vector<string> vecStr;
string pStr1 = "Robb";
vecStr.push_back(pStr1);
string pStr2 = "Bran";
vecStr.push_back(pStr2);
string pStr3 = "Snow";
vecStr.push_back(pStr3);
string pStr4 = "Sansa";
vecStr.push_back(pStr4);
string pStr5 = "Arya";
vecStr.push_back(pStr5); /*打印*/
for(auto unit:vecStr)
{
cout<<"-----"<<unit<<"-----"<<endl;
}
/*释放前vector的容量*/
cout<<"释放前vector的容量"<<endl; cout<<"vecStr.size() :"<<vecStr.size()<<endl;
cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl; /*释放*/
vecStr.clear();
cout<<endl<<"clear后vector的容量"<<endl; cout<<"vecStr.size() :"<<vecStr.size()<<endl;
cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl;
system("pause");
return ;
}

输出结果如图:

size是变小了,但是capacity并没有变小。

我们加一下代码

     /*swap*/
vector<string>().swap(vecStr);
cout<<endl<<"swap后vector的容量"<<endl; cout<<"vecStr.size() :"<<vecStr.size()<<endl;
cout<<"vecStr.capacity():"<<vecStr.capacity()<<end

使用swap之后,就清空了capacity。

这是为什么呢?

vector由于是一个不定长存储的数据结构,每一次分配的大小都是比面前输入的数据个数略大一点(实际上也并不准确,参看2)code中注释,是介于2^n与2^(n+1)之间),所以每一次push_back()且发现当被分配的存储空间已装满数据时,都是将包含现有数据的vector进行拷贝,进入一个更大一点的vector,而原有的vector就会被自然销毁,我们用.swap()释放内存的原理其实是相似的,即手动进行了一次人工拷贝的操作。(https://blog.csdn.net/a272846945/article/details/51182144 )

由于vector的空间是阶梯递增式管理的,而且基本只增不减,也就是说,虽然调用remove、erase或者clear等方法(他们会调用所存元素对象的析构函数),确实会释放掉一些内存,但是,容器之前分配的空间仍不会被回收,大小不变,仍旧不能被其他程序使用,这是由STL的内存管理机制决定的,目的是为了提高效率。 (https://www.cnblogs.com/EE-NovRain/archive/2012/06/12/2546500.html)

下面有一个调用函数的例子,感觉还是有很多东西

①内存增长方式,指数增长。2^n。数量增大到capacity的时候,整体拷贝,然后析构之前的内存。

②push_back,调用复制构造函数。

 class CUnit
{
private:
/* data */
string m_name;
public: CUnit(string name)
{
m_name = name;
//cout<<this<<",create"<<endl;
}
~CUnit()
{
//delete member
cout<<this<<",destroy"<<endl;
}
CUnit(const CUnit & c)
{
//cout<<&c<<",param"<<endl;
//cout<<this<<",copy"<<endl;
}
string& getName(){return m_name;}
}; int main()
{
vector<CUnit> vecStr;
CUnit cUnit1 = CUnit("Robb");
vecStr.push_back(cUnit1); //此处调用复制构造函数 cout<<"push one"<<endl; cout<<"vecStr.size() :"<<vecStr.size()<<endl;
cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl; CUnit cUnit2 = CUnit("Bran");//size不够,多次复制构造
vecStr.push_back(cUnit2); cout<<"push two"<<endl; cout<<"vecStr.size() :"<<vecStr.size()<<endl;
cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl;
CUnit cUnit3 = CUnit("Snow");//size不够,多次复制构造
vecStr.push_back(cUnit3);
CUnit cUnit4 = CUnit("Arya");//size不够,多次复制构造
vecStr.push_back(cUnit4);
CUnit cUnit5 = CUnit("Sansa");//size不够,多次复制构造
vecStr.push_back(cUnit5);
cout<<"push five"<<endl;
cout<<"vecStr.size() :"<<vecStr.size()<<endl;
cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl;
cout<<endl; /*打印*/
for(auto unit:vecStr)
{
cout<<"-----"<<unit.getName()<<"-----"<<endl;
}
/*释放前vector的容量*/
cout<<"释放前vector的容量"<<endl; cout<<"vecStr.size() :"<<vecStr.size()<<endl;
cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl; /*释放*/
vecStr.clear();
cout<<endl<<"clear后vector的容量"<<endl; cout<<"vecStr.size() :"<<vecStr.size()<<endl;
cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl; /*swap*/
vector<CUnit>().swap(vecStr);
cout<<endl<<"swap后vector的容量"<<endl; cout<<"vecStr.size() :"<<vecStr.size()<<endl;
cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl; system("pause");
return ;
}

2.list的清内存

 class CUnit
{
private:
/* data */
string m_name;
public: CUnit(string name)
{
m_name = name;
//cout<<this<<",create"<<endl;
}
~CUnit()
{
//delete member
cout<<this<<",destroy"<<endl;
}
CUnit(const CUnit & c)
{
//cout<<&c<<",param"<<endl;
//cout<<this<<",copy"<<endl;
}
string getName(){cout<<this<<",copy"<<endl;return m_name;}
}; int main()
{
list<CUnit*> listStr;
CUnit *cUnit1 = new CUnit("Robb");
listStr.push_back(cUnit1); //此处调用复制构造函数 cout<<"push one"<<endl;
cout<<"listStr.size() :"<<listStr.size()<<endl; CUnit* cUnit2 = new CUnit("Bran");//size不够,多次复制构造
listStr.push_back(cUnit2); cout<<"push two"<<endl;
cout<<"listStr.size() :"<<listStr.size()<<endl;
CUnit *cUnit3 = new CUnit("Snow");//size不够,多次复制构造
listStr.push_back(cUnit3);
CUnit *cUnit4 = new CUnit("Arya");//size不够,多次复制构造
listStr.push_back(cUnit4);
CUnit *cUnit5 = new CUnit("Sansa");//size不够,多次复制构造
listStr.push_back(cUnit5); cout<<"push five"<<endl;
cout<<"listStr.size() :"<<listStr.size()<<endl;
cout<<endl; /*打印*/
for(list<CUnit*>::iterator it = listStr.begin(); it!=listStr.end();it++)
{
cout<<"-----"<<(*it)->getName()<<"-----"<<endl;
}
/*释放前list的容量*/
cout<<"释放前list的容量"<<endl;
cout<<"listStr.size() :"<<listStr.size()<<endl;
cout<<"~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
#if 1 //调用析构函数,清掉了list的内存
for(list<CUnit*>::iterator it = listStr.begin(); it!=listStr.end();)
{
delete *it;
listStr.erase(it++);
//cout<<"-----"<<(*it)->getName()<<"-----"<<endl;
} cout<<"释放后list的容量"<<endl;
cout<<"listStr.size() :"<<listStr.size()<<endl;
cout<<"~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
#endif #if 0 //并不会调用析构函数,只是清掉了list的内存
/*释放*/
listStr.clear();
cout<<endl<<"clear后list的容量"<<endl;
cout<<"listStr.size() :"<<listStr.size()<<endl;
cout<<"~~~~~~~~~~~~~~~~~~~~~~~~"<<endl; /*swap*/
cout<<endl<<"swap后list的容量"<<endl;
cout<<"listStr.size() :"<<listStr.size()<<endl;
cout<<"~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
#endif
system("pause");
return ;
}

①自己new的空间,自己delete然后再释放容器。

②不是new出来的,直接erase、remove和clear即可。这类链式存储,一个元素一个元素递增空间的结构,这些函数可以真正地改变list占用的内存大小。

感觉好多东西啊!今天的结束了!

参考文献:

https://www.cnblogs.com/EE-NovRain/archive/2012/06/12/2546500.html

https://philoscience.iteye.com/blog/1456509

https://blog.csdn.net/a272846945/article/details/51182144

https://blog.csdn.net/HW140701/article/details/76704583

C++——STL内存清除的更多相关文章

  1. STL 内存释放

    C++ STL 中的map,vector等内存释放问题是一个很令开发者头痛的问题,关于 stl内部的内存是自己内部实现的allocator,关于其内部的内存管理本文不做介绍,只是 介绍一下STL内存释 ...

  2. C++STL内存管理方法(g++版)

    STL作为C++的经典作品,一直备受人们关注.本文主要介绍STL的内存管理策略. 早期的STL内存管理 第一次接触STL源码是看侯捷先生的<STL源码剖析>,此书通俗易懂,剖析透彻,是极佳 ...

  3. STL内存配置器

    一.STL内存配置器的总体设计结构 1.两级内存配置器:SGI-STL中设计了两级的内存配置器,主要用于不同大小的内存分配需求,当需要分配的内存大小大于128bytes时, 使用第一级配置器,否则使用 ...

  4. STL内存分配

    STL内存创建 Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu  转载请标明来源 1.      Stl内存创建基类模板__malloc_alloc_tem ...

  5. STL内存管理

    1. 概述 STL Allocator是STL的内存管理器,也是最低调的部分之一,你可能使用了3年stl,但却不知其为何物. STL标准如下介绍Allocator the STL includes s ...

  6. STL—内存的配置与释放

    上一篇我们介绍了STL对象的构造与析构,这篇介绍STL内存的配置与释放. STL有两级空间配置器,默认是使用第二级.第二级空间配置器会在某些情况下去调用第一级空间配置器.空间配置器都是在allocat ...

  7. SGI STL内存配置器存在内存泄漏吗?

    阅读了SGI的源码后对STL很是膜拜,很高质量的源码,从中学到了很多.温故而知新!下文中所有STL如无特殊说明均指SGI版本实现. STL 内存配置器 STL对内存管理最核心部分我觉得是其将C++对象 ...

  8. C++技术问题总结-第8篇 STL内存池是怎么实现的

    STL内存池机制,使用双层级配置器.第一级採用malloc.free,第二级视情况採用不同策略. 这样的机制从heap中要空间,能够解决内存碎片问题. 1.内存申请流程图     简要流程图例如以下. ...

  9. C++STL内存配置的设计思想与关键源码分析

    说明:我认为要读懂STL中allocator部分的源码,并汲取它的思想,至少以下几点知识你要了解:operator new和operator delete.handler函数以及一点模板知识.否则,下 ...

随机推荐

  1. wc.exe

    1 /* 2 * 没能实现的功能:wc.exe -s递归处理目录下符合条件的文件 3 * wc.exe -x 显示图形界面 4 * 5 * 6 * 实现的功能: wc.exe -c显示文件的字符数. ...

  2. 对弈的C++学习笔记

    2018-07-11上传   一:从C到C++ 1.C++新类型 bool 判断真假 占用一个字节      if(条件) 真1或者假 0     bool 类型的取值 true false      ...

  3. 基于.NET平台常用的框架整理<转载>

    转载来自:http://www.cnblogs.com/hgmyz/p/5313983.html 基于.NET平台常用的框架整理   自从学习.NET以来,优雅的编程风格,极度简单的可扩展性,足够强大 ...

  4. AsyncTask RejectedExecutionException 小结

    在使用Asynctask时,相信有些朋友会遇到以下RejectedExecutionException: Java.util.concurrent.RejectedExecutionException ...

  5. Hibernate原理及应用

    Hibernate工作原理及为什么要用? 原理:1.通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件2.由hibernate.cfg.x ...

  6. vscode里使用.vue代码模板的方法

    1.设置.vue模板 打开编辑器,点击文件 —— 首选项 —— 用户代码片段,会弹出来一个输入框. 在输入框输入vue,回车,会打开一个vue.json文件. 在里面复制以下代码: { "P ...

  7. 提示Unused default export错误,如何解决

    问题描述如下: 这个错误提示其实是webstorm的变量语法检查提示,修改一下它的配置就好了. 1.点击Webstorm右下角的小人,点击Configure inspections 2.在搜索框中输入 ...

  8. python笔记——随手记

    1.max与min函数的使用min(0)返回该矩阵中每一列的最小值 min(1)返回该矩阵中每一行的最小值 max(0)返回该矩阵中每一列的最大值 max(1)返回该矩阵中每一行的最大值2.argso ...

  9. Python 子进程不能input

    from threading import Thread from multiprocessing import Process def f1(): name = input('请输入名字') #EO ...

  10. 博客 新址: https://pheromone.github.io/

    该博客暂时调整歇业,小店地址暂时搬迁至: https://pheromone.github.io/ 该博客只做旧文章的维护工作. 博客 新址:  https://pheromone.github.io ...