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的
                        // 第三个参数的类型
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐