【问题标题】:Memory allocation of values in a std::mapstd::map 中值的内存分配
【发布时间】:2013-05-18 04:51:29
【问题描述】:

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

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

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

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

编辑 2: 我想一个更精确的问题是:“使用 new-operator 将对象存储为指针,而不是普通值,在内存和资源上是否有区别?用的立场?”

【问题讨论】:

  • 对象通常应该存储在一个容器中。
  • 您所说的大部分内容要么不正确,要么仅部分正确。为T 定义析构函数并不意味着vector<T*> 在使用完对象后会自动删除它们。此外,对于 C++11 和移动语义,对容器中的对象被复制太多次的担忧是没有实际意义的。大约只有一次您想在容器中存储 T* 而不是 T 应该是当 T 由于某些数据成员的限制而不可复制和不可移动时。最后,您的问题到底是什么?
  • @Praetorian:“关于你想在容器中存储 T* 的唯一时间”=> 或用于多态性(指向基类的指针)。但在任何情况下,都应该避免将裸指针存储在容器中,而是更喜欢智能指针。
  • @Matzar 这如何帮助销毁vector 中包含的对象?多态性是我忘记的另一个合理原因。但请使用vector<unique_ptr<T>> 而不是vector<T*>
  • @Matzar 啊,现在我明白了。这行得通,但是如果您使用包含智能指针的容器来代替,则不需要编写它。始终努力编写不需要显式定义析构函数的类。或为此复制/移动构造函数/赋值运算符。请阅读标题为rule of zero的帖子。

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


【解决方案1】:

避免将完整对象存储在容器中(而不是指针)的主要原因是复制或移动这些对象的成本很高。在这种情况下,推荐的替代方法是将 smart 指针存储在容器中。

所以...

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&lt;string&gt; 很好,即使所有字符串都是兆字节长。如果sizeof(classname) 很大 - 如果对象在其内部而不是在单独的堆分配内存中保存大量数据,您主要担心移动对象的成本。

即便如此,您也不会总是担心移动物体的成本。如果你从不移动一个物体,那么移动它的代价并不重要。例如,map 不需要过多地移动项目。当您插入和删除项目时,节点(和包含的项目)保持原位,只是链接节点的指针发生了变化。

【讨论】:

  • 好的,非常感谢!我希望我能投票。 :) 这几乎就是我收集到的关于内存分配和指针的内容。但是我对对象的大小仍然有点迷茫(要知道复制/移动有问题的对象是否会很昂贵)。我必须做更多的研究。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-10
  • 2016-06-19
  • 1970-01-01
相关资源
最近更新 更多