Rule33:提防在指针的容器上使用类似remove的算法
我们可以分析出remove的算法流程,他像这样:
其中B和C对象是不合格的对象,需要从中删除,如果我们使用remove方法,得到的结果是这样:
因为他会将位置2,和3的指针值替换为4,5位置的值,形成一个有效区域(1-3)。这就是最后的有效区间。这个时候,对象B,C已经不能正常回收了。造成了资源泄漏。
然后经过erase方法之后,情况就是这样:
所以我们应该努力避免在动态分配的指针的容器上使用remove和类似算法如Remove_if。我们可以选择partition。
如果你无法避免在那样的容器上使用remove,排除这个问题一种方法是在应用erase-remove惯用法之前先删除指针并设置它们为空,然后除去容器中的所有空指针。
void delAndNullifyUncertified(Widget*& pWidget) // 如果*pWidget是一个未通过检验Widget,
{
if (!pWidget->isCertified()) { // 删除指针
delete pWidget; // 并且设置它为空
pWidget = 0;
}
}
for_each(v.begin(), v.end(), // 把所有指向未通过检验Widget的
delAndNullifyUncertified); // 指针删除并且设置为空
v.erase(remove(v.begin(), v.end(), // 从v中除去空指针
static_cast<Widget*>(0)), // 0必须映射到一个指针,
v.end()); // 让C++可以
// 正确地推出remove的
// 第三个参数的类型