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