C++ 释放std::vector保留的内存及其所在类的descrutor中的元素

C++ 释放std::vector保留的内存及其所在类的descrutor中的元素,c++,pointers,c++11,vector,stl,C++,Pointers,C++11,Vector,Stl,我想知道我是否应该手动释放std::vector保留的内存以及包含该向量的类的析构函数中的元素。如果是的话,具体情况如何 情况#1-基本类型的标准::向量: class A{ std::vector<int> elements; A(){...} }; class B{ int b; C * pointer; ... }; class A{ std::vector<B> elements; A(){...} };

我想知道我是否应该手动释放
std::vector
保留的内存以及包含该向量的类的析构函数中的元素。如果是的话,具体情况如何

情况#1-基本类型的标准::向量:

class A{
    std::vector<int> elements;
    A(){...}
};
class B{
    int b;
    C * pointer;
    ...
};

class A{
    std::vector<B> elements;
    A(){...}
};
class B{
    int b;
    C * pointer;
    ...
};

class A{
    std::vector<B*> elements;
    A(){...}
};
我想一想情况,当
元素
只属于
A
并且不被任何其他结构共享时(
A
被销毁时,
元素也应该被销毁

很明显,对于
std::vector
的指针,我必须在每个元素上使用
delete e

但是:

  • 我真的必须调用
    元素.clear()(对象将在该行之后被销毁-这不是在浪费指令吗)
  • 也许我也应该在循环中使用
    std::vector
    erase(…)
    方法如果是这样的话,
    clear()
    会为我做所有的工作吗(当
    std::vector
    不包含指针时)
  • 我错过什么了吗最好的方法是什么?

    p、 美国的情况#3是关于指针的,而不是共享指针

    我想知道我是否应该手动释放
    std::vector
    保留的内存以及包含该向量的类的析构函数中的元素

    不,你永远不需要那样做。与任何设计良好的RAII类型一样,标准容器在从容器中删除它们所包含的对象时会自动销毁它们(包括通过销毁容器来擦除所有元素)

    显然,对于指针的std::vector,我必须在每个元素上使用
    delete e

    只有当您滥用指针来暗示它们指向的对象的所有权时。我们有智能指针来明确所有权,并在正确的时间自动删除对象

    我真的必须调用
    元素.clear()

    不,毁灭者会处理的

    也许我也应该在循环中使用
    std::vector
    erase(…)
    方法

    不,那会更糟。它将使循环使用的迭代器无效,从而给出未定义的行为。析构函数将为您擦除所有元素

    最好的方法是什么


    尽可能存储对象。如果您需要指针,如果您希望容器“拥有”对象,请存储智能指针;如果您以其他方式管理对象,只希望容器引用对象,请存储常规指针(或弱指针)。

    很明显,对于std::vector指针,我必须在每个元素上使用delete e真的吗<代码>标准::向量iv;int x;iv.推回(&x)
    Call
    delete
    并观察火花飞溅。规则很简单——std::vector知道如何删除它自己的动态分配内存,该内存用于管理其内部数组。如果你的类创建了自己的动态分配内存,你就有责任清理它。@PaulMcKenzie我相信你没有足够仔细地阅读这个问题。阅读情景3描述(粗体):“复杂类型指针的std::vector”
    int
    不是复杂类型。关于第二条评论:你假设在每种情况下,空的析构函数对A来说都很好,对吗?当然,不包括删除e
    。类型是否“复杂”并不重要。我可以很容易地创建一个“复杂”类型作为全局或堆栈,并将其地址粘贴到向量中。也许这是对你问题的一种迂回的回答——向量无法知道指针来自何处或指向何种类型的内存,因此它不可能通过发出
    delete
    调用来“删除”它。好吧,我错过了你以错误方式使用它的情况。但是在我的情况下,应该避免推回(&member)(而且,
    元素
    是私有的,所以这样的事情只能在一个内部发生)。我使用
    vector
    的目的是存储指向动态分配对象的指针(在其他情况下,我可以使用
    vector
    ),使用
    new
    属性创建-很抱歉没有从一开始就指定它。感谢您的逐步回答。然而,我必须提到,在某些特定情况下,我使用常规指针,并且有理由使用它们而不是智能指针——但我想这是离题的。再次感谢您给出明确的答案。@PolGraphic:无论这些原因是什么,它们都会导致代码无法维护,内存泄漏,甚至更糟,毫无益处。再想想它们是否是好的理由,然后无论如何都要使用智能指针。如果没有好处,就没有理由了。我怀疑你能认为不认识他们。可以肯定的是,它不仅仅是“导致代码内存泄漏”—它“导致代码
    最多只能
    内存泄漏”(我部分同意)。我认为我们不应该继续讨论指针和智能指针,因为这是一个非常离题的问题。让我们保持简单。事实上,如果你被这些“理由”说服,请不要理我。你要求“最好的方法”,所以我的建议是正确的。
    
    A::~A(){
        for(auto &e : elements){
            delete e;
        }
        elements.clear();
    }