容器中的对象如果是指针,指针指向的资源,容器没有办法自动释放.
问题引出
容器在自己析构的时候,会把包含的对象逐个析构掉. 这样容器包含的对象占用的资源就会被正确释放. 但如果容器里面存放的是指针,普通指针并没有析构函数,那么指针指向的资源,并不能被触发进行释放.
void main()
{
vector<Widget*> vwp;
for(int i = 0;i<10;i++)
{
vwp.push_back(new Widget);
}
}
当main函数执行完毕的时候,就有10个new的Widget对象泄露.
粗陋的解决方法
在使用完vwp容器之后,对容器内的指针手动释放一次
for(auto it=vwp.begin();it!=vwp.end();it++)
delete *it;
用for_each 取代for循环
使用for_each的好处,相对于手写for循环, for_each把事情拆分成了两部分,一部分是遍历元素,一部分是每个元素要执行的动作. 更易于理解. 针对上述的delete代码,可以参考下面的代码使用for_each修改
void delSrc(char *pSrc)
{
delete[] pSrc;
}
int main()
{
vector<char*> vecCharSrc;
for (int i = 1; i <= 10; i++)
{
char* pChar = new char[i];
vecCharSrc.push_back(pChar);
}
std::for_each(vecCharSrc.begin(), vecCharSrc.end(), delSrc);
}
避免手动释放,利用带计数的智能指针
void delSrc(char *pSrc)
{
delete[] pSrc;
}
int main()
{
vector<std::shared_ptr<char>> vecCharSrc;
for (int i = 1; i <= 10; i++)
{
std::shared_ptr<char> pSrc(new char[i], delSrc);
vecCharSrc.push_back(pSrc);
}
}
利用shared_ptr 封装new出来的资源,具有自动释放的能力,比手动写释放资源代码更安全. 即使发生异常,也不会泄露,因为异常会触发各自的析构函数,而shared_ptr对象的析构函数会自动去调用delSrc函数完成资源释放.
注意,虽然auto_ptr一样有自动的资源释放能力,但是auto_ptr没有计数能力,放到容器里,极易引起误用. 请参考第八条.
网友评论