【问题标题】:Memory management with new keyword and an STL vector of pointers使用 new 关键字和 STL 指针向量进行内存管理
【发布时间】:2010-12-28 14:31:54
【问题描述】:

向该列表添加元素时,向量的析构函数是如何管理的?对象超出范围时是否正确销毁?是否存在无法正确删除对象的情况?例如,如果“表”是对象的子对象,并且我们将新表添加到对象指针向量中,会有什么后果?

vector <object*> _objectList;

_objectList.PushBack(new object);

【问题讨论】:

    标签: c++ stl


    【解决方案1】:

    由于您正在制作“裸”指针的向量,C++ 不可能知道所讨论的指针意味着拥有它们指向的对象的“所有权”,因此它不会调用这些对象'指针消失时的析构函数。您应该使用简单的“智能”指针而不是“裸”指针作为vector 的项目。例如,Boost 的shared_ptr 将完全适合该任务(尽管如果您不想将 Boost 作为一个整体处理并且没有其他需要代码中的智能指针)。

    编辑:因为您(OP)说使用诸如 Boost 之类的框架是不可行的,并且一些 cmets 有用地指出,即使 包装 std::auto_ptr并不能真正成为一个体面的快捷方式,您可能必须实现自己的智能指针(或者,如果您发现一个看起来可用的开源、独立的智能指针模板类,请审核它是否符合您的要求)。这个article 是 C++ 中智能指针的有用入门,无论您必须自己滚动还是审核现有实现。

    【讨论】:

    • 我知道 boost 库,但我仅限于使用 STL。
    • auto_ptr 不支持复制语义。因此,绝对不支持将其放入向量中,甚至将其包装在您自己的类中也会很棘手。
    • 特别是 auto_ptr 的复制构造函数和 operator= 采用非常量引用参数(这是有道理的,因为它们修改了参数)。因此,您几乎可以创建一个大小为零的向量,但您无能为力。向向量添加内容的函数都采用 const 参数,因此当它们尝试从 const auto_ptr 复制/赋值时,它们不会编译。
    • 上面链接的文章非常好,并且来自一个非常有名的来源“Andrei Alexandrescu”。但另一个著名的消息来源“Scott Myers”描述了他自己开发智能指针的经历。即使经过广泛的同行评审和出版;在它出版后的几年里,仍然需要更正。他的基本建议是不要自己构建,因为它比最初出现的要复杂得多。
    • @Martin,确实,如果可以使用经过验证的现有框架(如 Boost),它可以省去麻烦——但 OP 明确表示这不是他们的选择。至少它们必须只支持一个用例:此类智能指针的向量——因此,并非所有可能的问题都会出现。
    【解决方案2】:

    STL Vectors 会复制您放入其中的任何内容,并最终删除该副本。

    所以在这种情况下,向量存储的是一个指向对象的指针——而不是对象本身。所以它会复制指针,并删除指针。但是,as Chris said,对象本身不会被删除。

    所以,解决方案:

    如果你真的不需要使用指针,那就不要:

    vector <object> _objectList;
    _objectList.PushBack(object());
    

    如果您确实需要使用指针,您可以使用智能指针(它为您处理引用计数,并将与指针一起删除对象),如 Alex suggested,或使用 ptr_vector,as Igor mentioned .

    【讨论】:

    • 不幸的是必须使用指针,因为基类有一些抽象方法
    【解决方案3】:

    您可以使用 bost 'ptr_vector'。当项目被删除或ptr_vector 的实例超出范围时,它将自动销毁项目指向的对象。更多信息可通过here获得。

    【讨论】:

    • 我希望在我还在做大量 C++ 的时候就知道这一点!
    【解决方案4】:

    在您的情况下,对象指针被正确销毁,但实际对象本身不会被触及。 STL 正确地破坏了所有包含的元素 - 但不会隐式取消引用指向类型的指针。

    【讨论】:

    • 那么如何销毁对象本身呢?
    • 您需要自己遍历向量和delete 指针。
    • @ZoogieZork 是正确的 - 迭代和删除。另一种选择(正如其他人所建议的)是使用智能指针类型。
    猜你喜欢
    • 2014-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    • 2010-09-23
    • 1970-01-01
    • 2011-12-12
    • 2015-02-03
    相关资源
    最近更新 更多