C++——STL内存清除
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内存清除的更多相关文章
- STL 内存释放
C++ STL 中的map,vector等内存释放问题是一个很令开发者头痛的问题,关于 stl内部的内存是自己内部实现的allocator,关于其内部的内存管理本文不做介绍,只是 介绍一下STL内存释 ...
- C++STL内存管理方法(g++版)
STL作为C++的经典作品,一直备受人们关注.本文主要介绍STL的内存管理策略. 早期的STL内存管理 第一次接触STL源码是看侯捷先生的<STL源码剖析>,此书通俗易懂,剖析透彻,是极佳 ...
- STL内存配置器
一.STL内存配置器的总体设计结构 1.两级内存配置器:SGI-STL中设计了两级的内存配置器,主要用于不同大小的内存分配需求,当需要分配的内存大小大于128bytes时, 使用第一级配置器,否则使用 ...
- STL内存分配
STL内存创建 Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu 转载请标明来源 1. Stl内存创建基类模板__malloc_alloc_tem ...
- STL内存管理
1. 概述 STL Allocator是STL的内存管理器,也是最低调的部分之一,你可能使用了3年stl,但却不知其为何物. STL标准如下介绍Allocator the STL includes s ...
- STL—内存的配置与释放
上一篇我们介绍了STL对象的构造与析构,这篇介绍STL内存的配置与释放. STL有两级空间配置器,默认是使用第二级.第二级空间配置器会在某些情况下去调用第一级空间配置器.空间配置器都是在allocat ...
- SGI STL内存配置器存在内存泄漏吗?
阅读了SGI的源码后对STL很是膜拜,很高质量的源码,从中学到了很多.温故而知新!下文中所有STL如无特殊说明均指SGI版本实现. STL 内存配置器 STL对内存管理最核心部分我觉得是其将C++对象 ...
- C++技术问题总结-第8篇 STL内存池是怎么实现的
STL内存池机制,使用双层级配置器.第一级採用malloc.free,第二级视情况採用不同策略. 这样的机制从heap中要空间,能够解决内存碎片问题. 1.内存申请流程图 简要流程图例如以下. ...
- C++STL内存配置的设计思想与关键源码分析
说明:我认为要读懂STL中allocator部分的源码,并汲取它的思想,至少以下几点知识你要了解:operator new和operator delete.handler函数以及一点模板知识.否则,下 ...
随机推荐
- Scrapy中间件user-agent和ip代理使用
一.定义实现随机User-Agent的下载中间件 1.在middlewares.py中完善代码 import random from Tencent.settings import USER_AGEN ...
- pyCharm中BeautifulSoup应用
BeautifulSoup 是第三方库的工具,它包含在一个名为bs4的文件包中,需要额外安装,安装方式 非常简单,进入python的安装目录,再进入scripts子目录,找到pip程序, pip in ...
- Problem 1: Multiples of 3 and 5
小白一枚,python解法,共同学习,一起进步. Problem 1: Multiples of 3 and 5 If we list all the natural numbers below 10 ...
- Codeforces Round #552 (Div. 3) F. Shovels Shop (前缀和预处理+贪心+dp)
题目:http://codeforces.com/contest/1154/problem/F 题意:给你n个商品,然后还有m个特价活动,你买满x件就把你当前的x件中最便宜的y件价格免费,问你买k件花 ...
- RedLock.Net - 基于Redis分布式锁的开源实现
工作中,经常会遇到分布式环境中资源访问冲突问题,比如商城的库存数量处理,或者某个事件的原子性操作,都需要确保某个时间段内只有一个线程在访问或处理资源. 因此现在网上也有很多的分布式锁的解决方案,有数据 ...
- php优秀框架codeigniter学习系列——CI_Input类学习
这篇文章主要介绍CI核心框架工具类CI_Input. 根据CI文档自己的定义,该类用来: 提前处理全局变量,以保证安全; 提供一些帮助函数用来处理输入数据. 以下选取类中的重点方法进行说明. __co ...
- like 内容转义
如题,当SQL语句中使用Like查询,且期望匹配的结果中含有"\"的,应当把"\"替换为"\\\\". 比如数据库中text字段有以下三行: ...
- type() 和 isinstance()区别
a=111 # type() 返回数据类型 In: type(a) Out: int In: print(type(a)) Out: <class 'int'> # isinstance ...
- .net 客户端调用java或.net webservice进行soapheader验证
.net 客户端调用java或.net webservice进行soapheader验证 最近项目中有业务需要跨平台调用web服务,客户端和服务器之间采用非对称加密来保证数据的安全性,webservi ...
- 如何让浏览器直接输出HTML代码而不解析
方法一: 将HTML代码嵌入到<script type='text/html' style='display:block'></scipt>中 <script type= ...