C++——STL内存清除
1.vector元素的清除
看代码。在vector中添加若干元素,然后clear()
1 #include<iostream> 2 #include<list> 3 #include<vector> 4 #include<iterator> 5 #include<string> 6 using std::vector; 7 using std::list; 8 using std::iterator; 9 using std::string; 10 using std::cout; 11 using std::endl; 12 13 int main() 14 { 15 vector<string> vecStr; 16 string pStr1 = "Robb"; 17 vecStr.push_back(pStr1); 18 string pStr2 = "Bran"; 19 vecStr.push_back(pStr2); 20 string pStr3 = "Snow"; 21 vecStr.push_back(pStr3); 22 string pStr4 = "Sansa"; 23 vecStr.push_back(pStr4); 24 string pStr5 = "Arya"; 25 vecStr.push_back(pStr5); 26 27 /*打印*/ 28 for(auto unit:vecStr) 29 { 30 cout<<"-----"<<unit<<"-----"<<endl; 31 } 32 /*释放前vector的容量*/ 33 cout<<"释放前vector的容量"<<endl; 34 35 cout<<"vecStr.size() :"<<vecStr.size()<<endl; 36 cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl; 37 38 /*释放*/ 39 vecStr.clear(); 40 cout<<endl<<"clear后vector的容量"<<endl; 41 42 cout<<"vecStr.size() :"<<vecStr.size()<<endl; 43 cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl; 46 system("pause"); 47 return 0; 48 }
输出结果如图:
size是变小了,但是capacity并没有变小。
我们加一下代码
1 /*swap*/ 2 vector<string>().swap(vecStr); 3 cout<<endl<<"swap后vector的容量"<<endl; 4 5 cout<<"vecStr.size() :"<<vecStr.size()<<endl; 6 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,调用复制构造函数。
1 class CUnit 2 { 3 private: 4 /* data */ 5 string m_name; 6 public: 7 8 CUnit(string name) 9 { 10 m_name = name; 11 //cout<<this<<",create"<<endl; 12 } 13 ~CUnit() 14 { 15 //delete member 16 cout<<this<<",destroy"<<endl; 17 } 18 CUnit(const CUnit & c) 19 { 20 //cout<<&c<<",param"<<endl; 21 //cout<<this<<",copy"<<endl; 22 } 23 string& getName(){return m_name;} 24 }; 25 26 27 int main() 28 { 29 vector<CUnit> vecStr; 30 CUnit cUnit1 = CUnit("Robb"); 31 vecStr.push_back(cUnit1); //此处调用复制构造函数 32 33 cout<<"push one"<<endl; 34 35 cout<<"vecStr.size() :"<<vecStr.size()<<endl; 36 cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl; 37 38 39 CUnit cUnit2 = CUnit("Bran");//size不够,多次复制构造 40 vecStr.push_back(cUnit2); 41 42 cout<<"push two"<<endl; 43 44 cout<<"vecStr.size() :"<<vecStr.size()<<endl; 45 cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl; 46 CUnit cUnit3 = CUnit("Snow");//size不够,多次复制构造 47 vecStr.push_back(cUnit3); 48 CUnit cUnit4 = CUnit("Arya");//size不够,多次复制构造 49 vecStr.push_back(cUnit4); 50 CUnit cUnit5 = CUnit("Sansa");//size不够,多次复制构造 51 vecStr.push_back(cUnit5); 52 cout<<"push five"<<endl; 53 cout<<"vecStr.size() :"<<vecStr.size()<<endl; 54 cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl; 55 cout<<endl; 56 57 /*打印*/ 58 for(auto unit:vecStr) 59 { 60 cout<<"-----"<<unit.getName()<<"-----"<<endl; 61 } 62 /*释放前vector的容量*/ 63 cout<<"释放前vector的容量"<<endl; 64 65 cout<<"vecStr.size() :"<<vecStr.size()<<endl; 66 cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl; 67 68 /*释放*/ 69 vecStr.clear(); 70 cout<<endl<<"clear后vector的容量"<<endl; 71 72 cout<<"vecStr.size() :"<<vecStr.size()<<endl; 73 cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl; 74 75 /*swap*/ 76 vector<CUnit>().swap(vecStr); 77 cout<<endl<<"swap后vector的容量"<<endl; 78 79 cout<<"vecStr.size() :"<<vecStr.size()<<endl; 80 cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl; 81 82 system("pause"); 83 return 0; 84 }
2.list的清内存
1 class CUnit 2 { 3 private: 4 /* data */ 5 string m_name; 6 public: 7 8 CUnit(string name) 9 { 10 m_name = name; 11 //cout<<this<<",create"<<endl; 12 } 13 ~CUnit() 14 { 15 //delete member 16 cout<<this<<",destroy"<<endl; 17 } 18 CUnit(const CUnit & c) 19 { 20 //cout<<&c<<",param"<<endl; 21 //cout<<this<<",copy"<<endl; 22 } 23 string getName(){cout<<this<<",copy"<<endl;return m_name;} 24 }; 25 26 27 int main() 28 { 29 list<CUnit*> listStr; 30 CUnit *cUnit1 = new CUnit("Robb"); 31 listStr.push_back(cUnit1); //此处调用复制构造函数 32 33 cout<<"push one"<<endl; 34 cout<<"listStr.size() :"<<listStr.size()<<endl; 35 36 CUnit* cUnit2 = new CUnit("Bran");//size不够,多次复制构造 37 listStr.push_back(cUnit2); 38 39 cout<<"push two"<<endl; 40 cout<<"listStr.size() :"<<listStr.size()<<endl; 41 CUnit *cUnit3 = new CUnit("Snow");//size不够,多次复制构造 42 listStr.push_back(cUnit3); 43 CUnit *cUnit4 = new CUnit("Arya");//size不够,多次复制构造 44 listStr.push_back(cUnit4); 45 CUnit *cUnit5 = new CUnit("Sansa");//size不够,多次复制构造 46 listStr.push_back(cUnit5); 47 48 cout<<"push five"<<endl; 49 cout<<"listStr.size() :"<<listStr.size()<<endl; 50 cout<<endl; 51 52 /*打印*/ 53 for(list<CUnit*>::iterator it = listStr.begin(); it!=listStr.end();it++) 54 { 55 cout<<"-----"<<(*it)->getName()<<"-----"<<endl; 56 } 57 /*释放前list的容量*/ 58 cout<<"释放前list的容量"<<endl; 59 cout<<"listStr.size() :"<<listStr.size()<<endl; 60 cout<<"~~~~~~~~~~~~~~~~~~~~~~~~"<<endl; 61 #if 1 //调用析构函数,清掉了list的内存 62 for(list<CUnit*>::iterator it = listStr.begin(); it!=listStr.end();) 63 { 64 delete *it; 65 listStr.erase(it++); 66 //cout<<"-----"<<(*it)->getName()<<"-----"<<endl; 67 } 68 69 cout<<"释放后list的容量"<<endl; 70 cout<<"listStr.size() :"<<listStr.size()<<endl; 71 cout<<"~~~~~~~~~~~~~~~~~~~~~~~~"<<endl; 72 #endif 73 74 #if 0 //并不会调用析构函数,只是清掉了list的内存 75 /*释放*/ 76 listStr.clear(); 77 cout<<endl<<"clear后list的容量"<<endl; 78 cout<<"listStr.size() :"<<listStr.size()<<endl; 79 cout<<"~~~~~~~~~~~~~~~~~~~~~~~~"<<endl; 80 81 /*swap*/ 82 cout<<endl<<"swap后list的容量"<<endl; 83 cout<<"listStr.size() :"<<listStr.size()<<endl; 84 cout<<"~~~~~~~~~~~~~~~~~~~~~~~~"<<endl; 85 #endif 86 system("pause"); 87 return 0; 88 }
①自己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
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步