std :: vector.clear()是否在每个元素上删除(空闲内存)?

时间:2009-02-27 09:26:37

标签: c++ std

考虑以下代码:

#include <vector>

void Example()
{
    std::vector<TCHAR*> list;
    TCHAR* pLine = new TCHAR[20];
    list.push_back(pLine);
    list.clear();    // is delete called here?
    // is delete pLine; necessary?
}

list.clear()是否在每个元素上调用delete?即我必须在list.clear()之前/之后释放内存吗?

6 个答案:

答案 0 :(得分:48)

当调用clear()时,

std :: vector会调用它包含的每个元素的析构函数。 在您的特定情况下,它会破坏指针但对象仍然存在。

智能指针是正确的方法,但要小心。 auto_ptr不能在std容器中使用。 boost :: scoped_ptr也不能。 boost :: shared_ptr可以,但它不会在你的情况下工作,因为你没有指向对象的指针,你实际上是在使用数组。因此,问题的解决方案是使用boost::shared_array

但是我建议你使用std :: basic_string,你不必处理内存管理,同时仍然可以使用字符串。

答案 1 :(得分:33)

否(你需要在你的例子中自己进行删除,因为光头指针的破坏不会做任何事情)。但你可以使用boost [或其他基于RAII的成语]智能指针使它做正确的事情(auto_ptr无法在容器中正常工作,因为它在复制等情况下具有不兼容的行为),但请确保你了解这些智能指针在使用前的缺陷。 (正如Benoit所提到的,在这种情况下,basic_string正是你在这里寻找的。)

已经说过需要理解智能指针的缺陷,让他们隐含地处理内存管理,所以你不必明确地做它就容易出错。

编辑:由于来自Earwicker和James Matta的强烈推动,我们进行了大幅修改,以包含Benoit带来的更为彻底的答案元素 - 感谢您促使我对此做出尽职调查!

答案 2 :(得分:8)

您可以编写一个简单的模板函数来为您执行此操作:

template <class T>
void deleteInVector(vector<T*>* deleteme) {
    while(!deleteme->empty()) {
        delete deleteme->back();
        deleteme->pop_back();
    }

    delete deleteme;
}

这里的某些事情可能是不好的做法,但我不这么认为。虽然评论总是很好,但对我来说看起来还不错。

答案 3 :(得分:7)

这是一种可以告诉它没有的方法 - 在未完全定义的类上尝试:

#include <vector>
class NotDefined;

void clearVector( std::vector<NotDefined*>& clearme )
{
    clearme.clear();    // is delete called here?
}

如果此代码段编译,则无法调用析构函数,因为未定义析构函数。

答案 4 :(得分:5)

不。它没有这样做,因为不能保证你没有在其他任何地方使用指针。如果它不是指针变量,它将释放它们(通过调用析构函数)

答案 5 :(得分:0)

您也可以使用Boost Pointer Container Library。这里没有特别推荐(再次因为你使用的是数组而不是单个对象,尽管std::string会照顾它),但它是一个有用且鲜为人知的库,可以解决标题中陈述的问题。