代码之家  ›  专栏  ›  技术社区  ›  Brian

C++集合中对象的内存管理

  •  3
  • Brian  · 技术社区  · 15 年前

    我有一个映射,它把整数和(物体的)向量联系起来。这些向量表示要执行的一组任务。为了减少在使用这个映射和向量时进行的复制量,我将它们设置为使用指针。

    std::map<int, std::vector<MyObject *> *> myMap;
    

    在保存mymap的类的初始化过程中,我通过创建一个新的向量来填充mymap。

    然而,我关心的是内存管理。现在我把这些不同的对象放在堆里的某个地方,我负责在处理完它们后清理它们。我也知道,在程序完成之前,我永远不会完成这些任务。但是,如果有人决定用一种巧妙的方法来修改这个应用程序,那么10周后会怎么样呢?这将导致内存泄漏。

    我的问题是如何处理 适当的 释放这些对象的位置,以便即使通过STL函数删除这些对象,也能成功释放这些对象?

    非常感谢您的帮助,如果我错过了任何重要的事情,请告诉我! 谢谢!

    6 回复  |  直到 15 年前
        1
  •  4
  •   anon    15 年前

    我同意使用智能指针是一个很好的方法,但至少有两种选择:

    a)复印可能不像你想象的那么贵。尝试实现值映射

    std::map<int, std::vector<MyObject>> myMap;
    

    b)用一个自己的类来包装向量来替换向量。在该类析构函数中,处理释放。您还可以提供添加和删除myObjects的方法。

        2
  •  7
  •   Fire Lancer    15 年前

    使用智能指针增强:共享指针而不是原始指针,这样当对象被破坏时,它也将清除堆分配的内存。

    Boost::共享资源 http://www.boost.org/doc/libs/1_39_0/libs/smart_ptr/shared_ptr.htm

    还有没有真正的原因有指向向量的指针?它们几乎不占用任何空间,并且std::map中的对象也不会移动(与向量中的对象不同,向量每次重新分配时都会移动/复制这些对象,例如获取更多空间)。

    编辑: 另外,shared-ptr是tr1的一个组件,我很确定它在下一个标准中,所以您的编译器可能已经有了它。还有很多其他智能指针可以让你知道如何写自己的东西,在谷歌上快速搜索就能找到它们。

    编辑2: 刚刚检查过,并且Visual Studio 2008的TR1实现包括共享的_ptr,它包含在 Visual C++ 2008 Feature Pack . 我预计许多其他供应商至少有部分TR1的实现可用,所以如果您不使用VS,请在供应商网站上搜索TR1支持。

        3
  •  1
  •   Draemon    15 年前

    使用共享指针(如其他人建议的)是最佳解决方案。

    如果你真的知道你会的话 从未 对他们了如指掌,那么他们就不需要再交易了。如果这真的是所期望的行为,只需记录下来,这样就不会有人在10周内出现,并将其误认为是真正的泄漏。

        4
  •  1
  •   Brian    15 年前

    谢谢大家的回答。我认为目前我倾向于一个价值向量的解决方案。主要原因是std::auto_ptr不适用于集合,因为它不可复制。这将是一个智能指针的唯一实现,我可以在不经历繁重的审查过程或滚动自己的过程的情况下使用它。

    好消息是你的回答引导我走了一条很好的路。我了解了RAII,关于异常处理的危险以及如何将它们最小化,并且在我的设计中保持足够的警惕,我可以对它的“正确性”感到满意。

    附件是一些我发现有帮助的链接。我希望任何遇到类似问题的人都能找到这些链接。

    RAII Resource
    Smart Pointers in C++
    Boost Smart Pointers
    More background/implementation details about Smart pointers

        5
  •  0
  •   TheUndeadFish    15 年前

    如果向量/映射中的不同条目之间没有共享每个指针的所有权,因此您只意味着减少在插入时完成的复制,那么您还应该考虑Boost Pointer Container 图书馆。

        6
  •  0
  •   Marc Mutz - mmutz    15 年前

    详细说明在使用时尽量减少复制 map<,vector<Object>> :

    仔细观察 map vector . 它们大多返回对所包含项的引用,如果在传递这些内容时保留引用,则不会进行复制。

    坏榜样:

    std::vector<MyObject> find_objects( const std::map<int,std::vector<MyObject>> & map, int i ) {
        const std::map<int,std::vector<MyObject>>::const_iterator it = map.find( i );
        if ( it != map.end() )
            return it->second;
        else
            return std::vector<MyObject>();
    }
    // ...
    const std::vector<MyObject> objects = find_objects(/*...*/);
    

    更好的:

    const std::vector<MyObject> & find_objects( const std::map<int,std::vector<MyObject>> & map, int i ) {
        const std::map<int,std::vector<MyObject>>::const_iterator it = map.find( i );
        if ( it != map.end() )
            return it->second;
        static const std::vector<MyObject> none();
        return none;
    }
    // ...
    const std::vector<MyObject> & objects = find_objects(/*...*/);
    

    ->禁止复制