容器内存释放问题(STL新手笔记)
最近看了下STL,用的過程中有一些體會需要記一下。
容器的空間申請和基本函數(shù)操作,以及algorithm等都比較好理解,用起來也很方便,比較關(guān)鍵的是容器元素包含指針時,空間的申請和釋放問題,這個覺得STL做得挺亂的??偨Y(jié)了幾點注意的。
?
1)自己new的空間,在釋放的時候必須先delete,然后再釋放容器。例如list<char*> MS,鏈表中存的是自己的動態(tài)字符串,如果字符串是自己動態(tài)申請的,則在釋放該鏈表的時候,需要先delete [](*curIter),然后再M(fèi)S.erase(curIter),其中curIter是當(dāng)前迭代器。
?
2)list的成員函數(shù)erase、remove和clear都會自動調(diào)用元素各自的析構(gòu)函數(shù),所以如果元素是自己定義的類,并且有完善的析構(gòu)函數(shù),則直接刪除即可。這類鏈?zhǔn)酱鎯?#xff0c;一個元素一個元素遞增空間的結(jié)構(gòu),這些函數(shù)可以真正地改變list占用的內(nèi)存大小。
?
3)vector等的空間釋放方式。需要注意兩點:
A、理解erase-remove慣用法,包括erase和remove函數(shù)的返回值等,http://blog.csdn.net/peteryxk/article/details/1804696這篇文章中講的比較清楚,下面是一個代碼示例:
View Code 1 /*刪除vector對象vec中等于10的元素,第一種方法*/ 2 for ( begin = vec.begin() ; begin != vec.end() ; /* ++begin */ ) 3 { 4 if ( 10 == *begin ) 5 { 6 begin = vec.erase( begin ) ; 7 } 8 else 9 { 10 ++begin ; 11 } 12 } 13 /*remove-erase方法*/ 14 vec.erase(remove (vec.begin() ,vec.end(),10) , vec.end()) ;需要搞明白remove和erase在這種順序結(jié)構(gòu)中的工作原理。
B、由于vector的空間是階梯遞增式管理的,而且基本只增不減,也就是,雖然調(diào)用remove、erase或者clear等方法(他們會調(diào)用所存元素對象的析構(gòu)函數(shù),如果元素是用戶定義的類,并且有完善析構(gòu)函數(shù)釋放掉該類的對象動態(tài)申請的空間,則remove和erase確實會釋放掉一些內(nèi)存,但是容器本身的空間還是難以被利用),容器之前分配的空間仍不會被回收,大小不變,仍舊不能被其他程序使用,這是由STL的內(nèi)存管理機(jī)制決定的,目的是為了提高效率。那么應(yīng)該怎么回收vector的內(nèi)存呢?這里就用了一個小的技巧,swap方法,代碼如下:
View Code { std::vector<int> tmp; vec.swap(tmp); }//使用一個局部變量空的容器temp,與vec交換,退出temp作用域后,temp會釋放自己的空間,而此時vec已經(jīng)是空的容器list由于是鏈?zhǔn)酱鎯Φ?#xff0c;跟vector機(jī)制不一樣,他的成員函數(shù)remove、erase、pop_front、pop_back和clear等都會回收被刪除元素的內(nèi)存空間,不需要swap協(xié)助。
對于vector,作如下實驗就可以看到,它的空間其實一直還是保留著的,除非swap掉:
View Code 1 vector<int> vec; 2 3 for(int i=1;i<=10;i++) 4 { 5 vec.push_back(i); 6 cout<<vec.size()<<" "<<vec.capacity()<<" "<<vec.max_size()<<endl; 7 } 8 cout<<endl; 9 for(int i=1;i<=10;i++) 10 { 11 vec.erase(remove(vec.begin(),vec.end(),i),vec.end()); 12 cout<<vec.size()<<" "<<vec.capacity()<<endl; 13 } 14 cout<<endl; 15 if(true) 16 { 17 vector<int> temp; 18 vec.swap(temp); 19 } 20 cout<<vec.size()<<" "<<vec.capacity()<<endl;運(yùn)行結(jié)果如下:
4)下面給出erase(刪除迭代器區(qū)間的內(nèi)容)和remove函數(shù)(一般用來刪除容器中等于特定值的內(nèi)容)的返回值定義,以方便理解3)A.
List::erase() Return value:
A bidirectional iterator pointing to the new location of the element that followed the last element erased by the function call, which is the list?end?if the operation erased the last element in the sequence.
List::remove() Return value: None
Vector::erase() Return value:
A random access iterator pointing to the new location of the element that followed the last element erased by the function call, which is the vector?end?if the operation erased the last element in the sequence.
非成員函數(shù),算法庫中的remove() Return value:
A forward iterator pointing to the new end of the range that includes all the elements with a value that does not compare equal to?value.
?
5)關(guān)于STL的內(nèi)存管理,有一篇文章http://philoscience.iteye.com/blog/1456509中好像說得挺清楚的,有空再看看。
?
轉(zhuǎn)載于:https://www.cnblogs.com/EE-NovRain/archive/2012/06/12/2546500.html
總結(jié)
以上是生活随笔為你收集整理的容器内存释放问题(STL新手笔记)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux 退出vi 命令简介
- 下一篇: 【日记】6.13