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

Ign*_*kas 59 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?
}
Run Code Online (Sandbox Code Playgroud)

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

Ben*_*oît 51

当调用clear()时,std :: vector会调用它包含的每个元素的析构函数.在您的特定情况下,它会销毁指针但对象仍然存在.

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

但我建议您使用std :: basic_string,在这里您不必处理内存管理,同时仍然可以获得使用字符串的好处.


Rub*_*ink 35

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

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

编辑:由于来自Earwicker和James Matta的强烈推动,大大修改了包括Benoit带来的更彻底答案的元素 - 感谢让我对此做出尽职调查!

  • auto_ptr无法使用.与STL容器一起使用时,auto_ptr会中断. (4认同)

tfi*_*iga 8

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

#include <vector>
class NotDefined;

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

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


Rob*_*oli 8

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

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

    delete deleteme;
}
Run Code Online (Sandbox Code Playgroud)

也许这里有些不好的做法,但我不这么认为.虽然评论总是很好,但对我来说看起来还不错.

  • 这是一个糟糕的做法。无处不在的指针使程序变得极其缓慢。如今编写快速程序的关键方法是始终使用连续的内存,最好的方法是直接使用向量&lt;T&gt;,T不是指针。 (2认同)

Meh*_*ari 5

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

  • @Ignas:std :: vector应该如何删除指针?它可能已经分配了new,malloc或任何其他内存分配函数(特定于OS,手写),没有办法从类型中分辨出来. (6认同)
  • 我保证不会在其他任何地方使用该指针. (2认同)