直接抛出两句话,说明到底应该如何释放Vector占用的内存。
“vector的clear不影响capacity,你应该swap一个空的vector。”
《Effective STL》中的“条款17”指出:
当vector、string大量插入数据后,即使删除了大量数据(或者全部都删除,即clear) 并没有改变容器的容量(capacity),所以仍然会占用着内存。 为了避免这种情况,我们应该想办法改变容器的容量使之尽可能小的符合当前数据所需(shrink to fit)。
释放方法
1.vector <T> 型释放内存
通过交换的方法。
1 template <class T> void ClearVector(vector<T>& v); 2 3 template <class T> 4 5 void ClearVector(vector<T>& v) 6 7 { 8 vector<T>vtTemp;//临时变量 9 10 vtTemp.swap(v); 11 12 v.shrink_to_fit(); 13 14 v.~vector<T>(); 15 }
2.vector <T*> 型释放内存
先删除容器内的指针的内存,最后删除容器。
1 vector<vector<int>*> m_contourSet;//待清空的变量,略去添加数据过程 2 3 for (int i = 0; i < m_contourSet.size(); i++)//清空每一个指针容器 4 { 5 vector<int>* pContour = m_contourSet[i]; 6 vector<int> st; 7 pContour->swap(st); 8 pContour->shrink_to_fit(); 9 pContour->~vector<int>(); 10 st.shrink_to_fit(); 11 st.~vector<int>(); 12 delete pContour;//删除指针 13 pContour = NULL; 14 } 15 16 ClearVector(m_contourSet);//最后清空容器
测试代码
下面的代码是在VS环境下的控制台程序,通过Visual Studio CRT测试内存泄漏,Debug模式下,在程序入口记录内存状态S1,出口处记录内存状态S2,比较S1和S2,记录在S3中,如果没有内存泄露,S3为0。实际结果当然是上面介绍的方法是正确可行的。
1 // TestMemoryLeak.cpp : Defines the entry point for the console application. 2 // 3 #include "stdafx.h" 4 #include <iostream> 5 #include <vector> 6 #define _CRTDBG_MAP_ALLOC 7 #include <stdlib.h> 8 #include <crtdbg.h> 9 10 using namespace std; 11 12 void FillDataOfVectorInt(vector<int>* m_Vector); 13 void FillDataOfVectorPointer(vector<vector<int>*>* m_Vector); 14 15 template <class T> void ClearVector(vector<T>& v); 16 17 int _tmain(int argc, _TCHAR* argv[]) 18 { 19 _CrtMemState s1, s2, s3; 20 _CrtMemCheckpoint(&s1); 21 22 vector<int> VectorInt; 23 vector<vector<int>*> VectorPointer; 24 25 FillDataOfVectorInt(&VectorInt); 26 FillDataOfVectorPointer(&VectorPointer); 27 28 //调用函数清空Vector 29 ClearVector(VectorInt); 30 //或者用下面代码 31 //vector<int>().swap(VectorInt); 32 //VectorInt.shrink_to_fit(); 33 //VectorInt.~vector<int>(); 34 35 ClearVector(VectormippPOINT3D); 36 37 //先清空Vector内的指针,再清空Vector 38 if (!VectorPointer.empty()) 39 { 40 for (int i = 0; i < VectorPointer.size(); i++) 41 { 42 vector<mippPOINT3D>* pContourPoint = VectorPointer.at(i); 43 if (pContourPoint != NULL) 44 { 45 vector<mippPOINT3D> st; 46 pContourPoint->swap(st); 47 pContourPoint->shrink_to_fit(); 48 pContourPoint->~vector<mippPOINT3D>(); 49 st.shrink_to_fit(); 50 st.~vector<mippPOINT3D>(); 51 52 delete pContourPoint;//delete和new是一一对应的 53 pContourPoint = NULL; 54 } 55 } 56 } 57 ClearVector(VectorPointer); 58 59 _CrtMemCheckpoint(&s2); 60 if (_CrtMemDifference(&s3, &s1, &s2)) 61 _CrtMemDumpStatistics(&s3); 62 63 return 0; 64 } 65 66 void FillDataOfVectorPointer(vector<vector<int>*>* m_Vector) 67 { 68 for (int j = 0; j < 100; j++) 69 { 70 vector<int>* pContourPointVec = new vector<int>; 71 pContourPointVec->clear(); 72 for (int i = 0; i < j + 100; i++) 73 { 74 pContourPointVec->push_back(i); 75 } 76 m_Vector->push_back(pContourPointVec); 77 } 78 79 } 80 81 void FillDataOfVectorInt(vector<int>* m_Vector) 82 { 83 m_Vector->clear(); 84 for (int i = 0; i < 1000000; i++) 85 { 86 m_Vector->push_back(i); 87 } 88 } 89 90 template <class T> 91 void ClearVector(vector<T>& v) 92 { 93 vector<T>vtTemp; 94 vtTemp.swap(v); 95 v.shrink_to_fit(); 96 v.~vector<T>(); 97 }