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. 基于uniGui开发的Delphi后台管理框架uniFramework

    uniGui是基于Delphi的一套开发Web应用的UI框架,前端使用的是ExtJS,最新版的uniGUI1.5 1480已支持新版的ExtJS6.5.3.我认为uniGUI是目前Delphi下最完善 ...

  2. Codeforces Round #162 (Div. 1) B. Good Sequences (dp+分解素数)

    题目:http://codeforces.com/problemset/problem/264/B 题意:给你一个递增序列,然后找出满足两点要求的最长子序列 第一点是a[i]>a[i-1] 第二 ...

  3. 说一下syslog日志吧~~~

    # -*- coding:utf-8 -*-from logging.handlers import *import loggingimport logging.handlers class MySo ...

  4. /usr/lib/x86_64-linux-gnu/libopencv_highgui.so:对‘TIFFReadRGBAStrip@LIBTIFF_4.0’未定义的引用

     LIBRARIES += boost_thread stdc++ boost_regex     https://github.com/rbgirshick/fast-rcnn/issues/52

  5. linux 增加虚拟内存swap(使用文件)

    1.简介 如果你的服务器的总是报告内存不足,并且时常因为内存不足而引发服务被强制kill的话,在不增加物理内存的情况下,启用swap交换区作为虚拟内存是一个不错的选择. 为了测试一些功能我在阿里云购买 ...

  6. WScript与CScript的区别

    WSH有两种形式:一为WScript是一个窗口化的版本:一为CScript是一个命令行的版本.两种版本都可以运行任何脚本.二者之间的区别是,窗口化版本(WScript)使用一个弹出对话框来显示文本输出 ...

  7. EditPlus软件自动补全文档htmlbar.acp设置 及 模板文件格式

    1.在htmlbar.acp文件末尾添加如下内容,可自动补全: #T=HTML <html>    ^! </html>   #T=HEAD <head>    ^ ...

  8. 基于Openstack环境下开启SRIOV

    主题思想: 先在系统层面修改配置文件,再去openstack里面修改配置文件 compute node系统层面: 先确认下是否含有ixgbe moudle lsmod |grep ixgbe 修改/e ...

  9. 中国科学技术大学第五届信息安全大赛(hackergame2018自我总结)2

    这一批题都是我不会的,只能把官方write-up放在这里了 1.FLXG 的秘密 ----------------------------------------------------------- ...

  10. Arch i3wm

    pacman -S i3-gaps i3blocks i3status dmenu xprofile设置 nano /home/user/,xprofile export LANG=zh_CN.UTF ...