有效清除矢量记忆

时间:2015-03-27 04:10:50

标签: c++

我正在创建一个像这样的矢量

vector<Member*> emp;

然后我像这样创建成员类的堆对象

Member* memObj = new Member();

然后像这样使用push_back

emp.push_back(memObj);

使用完所有函数之后我是否必须通过迭代来清除内存?

for( vector<Member*>::iterator iter = emp.begin();
                iter != emp.end(); )
{
    Member* mem = *iter;
    iter = emp.erase (iter); 
    delete mem;
    //iter++;
}

除了遍历每个值之外,还有其他有效的方法吗? clear函数只调用析构函数,它清除值但不释放内存..我希望在这里实现多态...我是C ++的新手....请帮助..提前谢谢.. :)我是使用C ++ 11

2 个答案:

答案 0 :(得分:6)

如果您能够使用C ++ 11编译器,则可以使用其中一个智能指针。

std::unique_ptr

std::vector<std::unique_ptr<Member>> emp;

std::shared_ptr

std::vector<std::shared_ptr<Member>> emp;

修改

如果您无法使用C ++ 11编译器,VS 2005肯定太旧而无法支持C ++ 11,您必须手动删除对象,就像您所示。

但是,我会添加一个帮助程序类来帮助delete Member个对象。

struct MemberDeleteHelper
{
    MemberDeleteHelper(std::vector<Member*> emp) : emp_(emp);

    ~MemberDeleteHelper()
    {
       for( vector<Member*>::iterator iter = emp.begin();
                iter != emp.end(); ++iter )
       {
          delete *iter;
       }
    }

    std::vector<Member*>& emp_;
};

并将其用作:

vector<Member*> emp;
MemberDeleteHelper deleteHelper(emp);

有了这个,无论你如何从函数返回,{@ 1}}的元素都将被删除。如果从嵌套函数调用中抛出异常,则将展开堆栈,并且仍将删除emp的元素。

编辑2

请勿在{{1​​}}中使用emp个对象。在http://www.devx.com/tips/Tip/13606讨论了在STL容器中使用auto_ptr的缺陷(感谢@pstrjds链接)。

答案 1 :(得分:4)

除非您的意图是将Member派生的类型实例添加到vector,否则不需要vector<Member*>,只需使用vector<Member>

如果您确实需要动态分配,请使用vector<unique_ptr<Member>>。当delete clear()时,智能指针会自动vector实例。如果是这种情况,请不要忘记Member需要virtual析构函数。

预C ++ 11编译器的类似选项是std::vector<std::tr1::shared_ptr<Member>>boost::ptr_vector<Member>


最后,您当前的代码有一个错误。 vector::erase返回指向下一个元素的指针,因此通过手动递增循环内的迭代器,您将跳过其他所有元素。而且我不明白为什么你会遇到将指针存储在临时变量中的麻烦。你的循环应该是

for( vector<Member*>::iterator iter = emp.begin(); iter != emp.end(); )
{
    delete *iter;
    iter = emp.erase(iter);
}

或者先删除所有元素,然后清除vector

for( vector<Member*>::iterator iter = emp.begin(); iter != emp.end(); ++iter)
{
    delete *iter;
}
emp.clear();