C++ C+中对象的内存管理+;收集

C++ C+中对象的内存管理+;收集,c++,memory-management,stl,containers,C++,Memory Management,Stl,Containers,我有一张将整数和向量(对象)联系起来的地图。这些向量表示要执行的一组任务。为了减少使用此映射和向量时进行的复制量,我将它们设置为使用指针 std::map<int, std::vector<MyObject *> *> myMap; std::map myMap; 在初始化保存myMap的类的过程中,我通过创建一个填充了新MyObject的新向量来填充myMap 然而,我关心的是内存管理。现在我把这些不同的东西放在堆的某个地方,我负责清理它们。我也知道,在计划完成之前

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

std::map<int, std::vector<MyObject *> *> myMap;
std::map myMap;
在初始化保存myMap的类的过程中,我通过创建一个填充了新MyObject的新向量来填充myMap

然而,我关心的是内存管理。现在我把这些不同的东西放在堆的某个地方,我负责清理它们。我也知道,在计划完成之前,我永远不会与他们断绝关系。但是,如果有人认为修改这个应用程序的一个聪明方法是从地图/矢量中删除项目,那么10周后会怎么样呢。这将导致内存泄漏

我的问题是如何处理这些对象的适当的解除分配,以便即使通过STL函数将它们删除,也能成功地解除分配这些对象

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

使用智能指针提升:共享而不是原始指针,这样当对象被销毁时,它也会清除堆分配的内存

boost::共享\u ptr

还有,真的有理由让指针指向向量吗?它们几乎不占用任何空间,并且std::map中的对象无论如何都不会移动(与向量中的对象不同,向量中的对象每次重新分配时都会移动/复制,例如为了获得更多空间)

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

编辑2: 刚刚检查过,VisualStudio2008的TR1实现包括共享的ptr,它包含在。我希望许多其他供应商至少有部分TR1的实现可用,因此如果您不使用VS,请搜索供应商站点以获得TR1支持。

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


如果你真的知道你永远不会与他们断绝关系,那么他们在技术上就不需要交易。如果这确实是需要的行为,只需记录下来,这样10周内就不会有人出现,并将其误认为是真正的泄漏

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

a) 复制可能没有你想象的那么昂贵。尝试实现一个值映射

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

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

>P>如果在指针/映射中不同的条目之间不共享每个指针的所有权,那么您只意味着减少插入时所做的复制,那么您也应该考虑Boost的库。

< P>谢谢所有的好答案。我认为目前我倾向于价值向量的解决方案。主要原因是std::auto_ptr不适用于集合,因为它是不可压缩的。这将是我能够使用的智能指针的唯一实现,而无需经过繁重的审查过程或自己滚动

好消息是你的回答让我走上了一条非常好的道路。我了解了RAII、异常处理的危险以及如何将其最小化,并对我的设计保持足够的警惕,使我对其“正确性”感到满意

附件是一些链接,我发现在这个过程中很有帮助。我希望任何遇到类似问题的人都会发现这些链接很有帮助





要详细说明在使用
map
时尽量减少复制,请执行以下操作:

仔细查看
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(/*...*/);
std::vector find_对象(const std::map&map,int i){
const std::map::const_迭代器it=map.find(i);
if(it!=map.end())
返回->秒;
其他的
返回std::vector();
}
// ...
const std::vector 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(/*...*/);
const std::vector和find_对象(const std::map和map,int i){
const std::map::const_迭代器it=map.find(i);
if(it!=map.end())
返回->秒;
静态常量std::vector none();
不返回任何值;
}
// ...
const std::vector&objects=查找对象(/*…*/);

->禁止复制

我希望找到一种解决方案,尽可能避免使用新库。不幸的是,任何新图书馆都必须经过审查。不过,我会调查这件事作为备用!boost对于你的项目来说是一件很好的事情,里面有很多有用的东西。然而,智能指针是你可以自己写的东西。我将用一个适合您需要的快速更新我的帖子。感谢地图上的提示,如果地图中没有欺骗数据,我可能可以避免指向向量,这使得处理起来容易得多。另外请注意,如果是2003年,shared_ptr只是一个“新库”。这是关于Tr1中最不具争议性的事情,它本身尽可能接近C++标准而不需要触摸。允许任意Boost库进入您的项目可能不是一个好主意(尤其是因为并非所有Boost库都有稳定的接口)。不过,shared_ptr是一个相当安全的赌注,值得一试,因为它正是为这个目的而设计的。允许它并不意味着你必须接受所有的刺激。