std :: map中值的内存分配

时间:2013-05-18 04:51:29

标签: c++ windows visual-c++ stl

我在学校的作品中有过一些C ++经验。除其他事项外,我已经了解到对象应该作为指针存储在容器(矢量,地图等)中。主要原因是我们需要使用new-operator和copy构造函数,以便在对象的堆(也称为动态内存)上创建副本。此方法还需要定义析构函数。

然而,从那时起我所读到的,似乎STL容器已经将它们包含的值存储在堆上。因此,如果我将对象存储为值,则无论如何都会在堆上创建副本(使用复制构造函数),并且不需要定义析构函数。总而言之,无论如何都会在堆上创建一个副本???

另外,如果(true),那么我能想到的使用指针存储对象的唯一原因就是减轻复制容器的资源需求,因为指针比整个对象更容易复制。但是,这需要使用std :: shared_ptr而不是常规指针,因为您不希望在销毁原始容器时删除复制容器中的元素。这种方法也可以减少定义析构函数的需要,不是吗?

编辑:要定义的析构函数是使用容器的类,而不是存储对象的类。

编辑2:我想更精确的问题是:“在内存和资源上使用new-operator而不是普通值存储对象作为指针是否有所不同?用过立场?“

1 个答案:

答案 0 :(得分:4)

避免在容器(而不是指针)中存储完整对象的主要原因是复制或移动这些对象非常昂贵。在这种情况下,建议的替代方法是将智能指针存储在容器中。

因此...

vector<something_t> ................. Usually perfectly OK
vector<shared_ptr<something_t>> ..... Preferred if you want pointers
vector<something_t*> ................ Usually best avoided

原始指针的问题在于,当原始指针消失时,它指向的对象会挂起导致内存和资源泄漏 - 除非您已明确删除它。 C ++没有垃圾收集,当指针被丢弃时,无法知道其他指针是否仍然指向该对象。

原始指针是一种低级工具 - 主要用于编写诸如vector和shared_ptr之类的库。智能指针是一个高级工具。

然而,特别是对于C ++ 11移动语义,即使对于大型对象,在向量中移动项目的成本通常也非常小。例如,即使所有字符串都是兆字节长,vector<string>都可以。如果sizeof(classname)很大,你最担心的是移动对象的成本 - 如果对象本身拥有大量数据而不是在单独的堆分配内存中。

即使这样,你也不会总是担心移动物体的成本。如果你从不移动它,移动一个物体是昂贵的并不重要。例如,map不需要移动很多项目。当您插入和删除项目时,节点(和包含的项目)将保持原样,它只是指向更改的节点的指针。