gpt4 book ai didi

c++ - std::map 中值的内存分配

转载 作者:可可西里 更新时间:2023-11-01 11:19:59 24 4
gpt4 key购买 nike

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

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

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

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

编辑 2: 我想一个更精确的问题是:“使用新运算符将对象存储为指针,而不是普通值,在内存和资源上有什么不同吗习惯的立场?”

最佳答案

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

所以...

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 中四处移动项目的成本通常非常小,即使对于巨大的对象也是如此。例如,vector<string>即使所有字符串都是兆字节长也很好。如果sizeof(classname),您主要担心移动物体的成本很大 - 如果对象在其自身内部而不是在单独的堆分配内存中包含大量数据。

即便如此,您也不必总是担心移动对象的成本。如果您从不移动对象,那么移动对象的代价高昂并不重要。例如,map不需要移动太多元素。当您插入和删除项时,节点(和包含的项)保持在原处,只是链接更改的节点的指针。

关于c++ - std::map 中值的内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16620801/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com