[C++]STL容器Vector的内存释放

时间:2021-08-04 02:33:03

直接抛出两句话,说明到底应该如何释放Vector占用的内存。

“vector的clear不影响capacity,你应该swap一个空的vector。”

《Effective STL》中的“条款17”指出:

当vector、string大量插入数据后,即使删除了大量数据(或者全部都删除,即clear) 并没有改变容器的容量(capacity),所以仍然会占用着内存。 为了避免这种情况,我们应该想办法改变容器的容量使之尽可能小的符合当前数据所需(shrink to fit)。


 释放方法

1.vector <T> 型释放内存

通过交换的方法。

 template <class T> void ClearVector(vector<T>& v);

 template <class T>

 void ClearVector(vector<T>& v)

 {
vector<T>vtTemp;//临时变量 vtTemp.swap(v); v.shrink_to_fit(); v.~vector<T>();
}

2.vector <T*> 型释放内存

先删除容器内的指针的内存,最后删除容器。

   vector<vector<int>*> m_contourSet;//待清空的变量,略去添加数据过程

   for (int i = ; i < m_contourSet.size(); i++)//清空每一个指针容器
{
vector<int>* pContour = m_contourSet[i];
vector<int> st;
pContour->swap(st);
pContour->shrink_to_fit();
pContour->~vector<int>();
st.shrink_to_fit();
st.~vector<int>();
delete pContour;//删除指针
pContour = NULL;
} ClearVector(m_contourSet);//最后清空容器

测试代码

下面的代码是在VS环境下的控制台程序,通过Visual Studio CRT测试内存泄漏,Debug模式下,在程序入口记录内存状态S1,出口处记录内存状态S2,比较S1和S2,记录在S3中,如果没有内存泄露,S3为0。实际结果当然是上面介绍的方法是正确可行的。

 // TestMemoryLeak.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <vector>
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h> using namespace std; void FillDataOfVectorInt(vector<int>* m_Vector);
void FillDataOfVectorPointer(vector<vector<int>*>* m_Vector); template <class T> void ClearVector(vector<T>& v); int _tmain(int argc, _TCHAR* argv[])
{
_CrtMemState s1, s2, s3;
_CrtMemCheckpoint(&s1); vector<int> VectorInt;
vector<vector<int>*> VectorPointer; FillDataOfVectorInt(&VectorInt);
FillDataOfVectorPointer(&VectorPointer); //调用函数清空Vector
ClearVector(VectorInt);
//或者用下面代码
//vector<int>().swap(VectorInt);
//VectorInt.shrink_to_fit();
//VectorInt.~vector<int>(); ClearVector(VectormippPOINT3D); //先清空Vector内的指针,再清空Vector
if (!VectorPointer.empty())
{
for (int i = ; i < VectorPointer.size(); i++)
{
vector<mippPOINT3D>* pContourPoint = VectorPointer.at(i);
if (pContourPoint != NULL)
{
vector<mippPOINT3D> st;
pContourPoint->swap(st);
pContourPoint->shrink_to_fit();
pContourPoint->~vector<mippPOINT3D>();
st.shrink_to_fit();
st.~vector<mippPOINT3D>(); delete pContourPoint;//delete和new是一一对应的
pContourPoint = NULL;
}
}
}
ClearVector(VectorPointer); _CrtMemCheckpoint(&s2);
if (_CrtMemDifference(&s3, &s1, &s2))
_CrtMemDumpStatistics(&s3); return ;
} void FillDataOfVectorPointer(vector<vector<int>*>* m_Vector)
{
for (int j = ; j < ; j++)
{
vector<int>* pContourPointVec = new vector<int>;
pContourPointVec->clear();
for (int i = ; i < j + ; i++)
{
pContourPointVec->push_back(i);
}
m_Vector->push_back(pContourPointVec);
} } void FillDataOfVectorInt(vector<int>* m_Vector)
{
m_Vector->clear();
for (int i = ; i < ; i++)
{
m_Vector->push_back(i);
}
} template <class T>
void ClearVector(vector<T>& v)
{
vector<T>vtTemp;
vtTemp.swap(v);
v.shrink_to_fit();
v.~vector<T>();
}