简体   繁体   English

std :: map中值的内存分配

[英]Memory allocation of values in a std::map

I've had some experience in C++ from school works. 我从学校的作品中学到了一些C ++经验。 I've learned, among other things, that objects should be stored in a container (vector, map, etc) as pointers. 除其他事项外,我已经了解到对象应该作为指针存储在容器(矢量,地图等)中。 The main reason being that we need the use of the new-operator, along with a copy constructor, in order to create a copy on the heap (otherwise called dynamic memory) of the object. 主要原因是我们需要使用new-operator和copy构造函数,以便在对象的堆(也称为动态内存)上创建副本。 This method also necessitates defining a destructor. 该方法还需要定义析构函数。

However, from what I've read since then, it seems that STL containers already store the values they contain on the heap. 但是,从那时起我所读到的,似乎STL容器已经将它们包含的值存储在堆上。 Thus, if I were to store my objects as values, a copy (using the copy constructor) would be made on the heap anyway, and there would be no need to define a destructor. 因此,如果我将对象存储为值,则无论如何都会在堆上创建副本(使用复制构造函数),并且不需要定义析构函数。 All in all, a copy on the heap would be made anyway??? 总而言之,无论如何都会在堆上创建一个副本???

Also, if(true), then the only other reason I can think of for storing objects using pointers would be to alleviate resource needs for copying the container, as pointers are easier to copy than whole objects. 另外,如果(true),那么我能想到的使用指针存储对象的唯一原因就是减轻复制容器的资源需求,因为指针比整个对象更容易复制。 However, this would require the use of std::shared_ptr instead of regular pointers, since you don't want elements in the copied container to be deleted when the original container is destroyed. 但是,这需要使用std :: shared_ptr而不是常规指针,因为您不希望在销毁原始容器时删除复制容器中的元素。 This method would also alleviate the need for defining a destructor, wouldn't it? 这种方法也可以减少定义析构函数的需要,不是吗?

Edit : The destructor to be defined would be for the class using the container, not for the class of the objects stored. 编辑:要定义的析构函数将用于使用容器的类,而不是用于存储的对象的类。

Edit 2 : I guess a more precise question would be : "Does it make a difference to store objects as pointers using the new-operator, as opposed to plain values, on a memory and resources used standpoint?" 编辑2:我想一个更精确的问题是:“使用new-operator将对象存储为指针,而不是使用普通值,在内存和资源使用的立场上是否有所作为?”

The main reason to avoid storing full objects in containers (rather than pointers) is because copying or moving those objects is expensive. 避免在容器(而不是指针)中存储完整对象的主要原因是复制或移动这些对象是昂贵的。 In that case, the recommended alternative is to store smart pointers in the container. 在这种情况下,推荐的替代方法是将智能指针存储在容器中。

So... 所以...

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

The problem with raw pointers is that, when a raw pointer disappears, the object it points to hangs around causing memory and resource leaks - unless you've explicitly deleted it. 原始指针的问题在于,当原始指针消失时,它指向的对象会挂起导致内存和资源泄漏 - 除非您已明确删除它。 C++ doesn't have garbage collection, and when a pointer is discarded, there's no way to know if other pointers may still be pointing to that object. C ++没有垃圾收集,当指针被丢弃时,无法知道其他指针是否仍然指向该对象。

Raw pointers are a low-level tool - mostly used to write libraries such as vector and shared_ptr. 原始指针是一种低级工具 - 主要用于编写诸如vector和shared_ptr之类的库。 Smart pointers are a high-level tool. 智能指针是一种高级工具。

However, particularly with C++11 move semantics, the costs of moving items around in a vector is normally very small even for huge objects. 但是,特别是对于C ++ 11移动语义,即使对于大型对象,在向量中移动项目的成本通常也非常小。 For example, a vector<string> is fine even if all the strings are megabytes long. 例如,即使所有字符串都是兆字节长, vector<string>也可以。 You mostly worry about the cost of moving objects if sizeof(classname) is big - if the object holds lots of data inside itself rather than in separate heap-allocated memory. 如果sizeof(classname)很大,你最担心的是移动对象的成本 - 如果对象本身拥有大量数据而不是在单独的堆分配内存中。

Even then, you don't always worry about the cost of moving objects. 即便如此,您并不总是担心移动物体的成本。 It doesn't matter that moving an object is expensive if you never move it. 如果你从不移动它,移动一个物体是昂贵的并不重要。 For example, a map doesn't need to move items around much. 例如, map不需要移动很多项目。 When you insert and delete items, the nodes (and contained items) stay where they are, it's just the pointers that link the nodes that change. 当您插入和删除项目时,节点(和包含的项目)保持原样,它只是链接更改的节点的指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM