问题描述
我正在与一个内存管理器,有时,想要碎片整理内存。基本上,我将浏览内存管理器分配的对象列表,并重新定位它们:
I am working with a memory manager that, on occasion, wants to defragment memory. Basically, I will go through a list of objects allocated by the memory manager and relocate them:
class A {
SomeClass* data; // This member is allocated by the special manager
};
for(... each instance of A ...)
a.data = memory_manager.relocate(a.data);
memory_manager.relocate()
将 memcpy()
将数据的内容移动到新位置,并返回指针。
memory_manager.relocate()
will memcpy()
the contents of data to a new location, and return the pointer.
虽然通常不是惯用的 memcpy()
C ++类,在这种情况下,它似乎是一个有用的解决方案,考虑到我控制(少数)类的实现将与内存管理器一起使用。
Although it's generally not idiomatic to memcpy()
C++ classes, it seems to be a useful solution in this case, considering that I control the implementation of the (few) classes that will be used with the memory manager.
问题是,其中一个类使用 std :: map
,这是一个不透明类我忧虑。我当然不想象我可以 memcpy()
它。我可能无法使用std :: map在任何情况下。对于所有我知道它可以分配几个内存。
The problem is that one of those classes uses std::map
, which is an opaque class as far as I am concerned. I certainly don't imagine I can memcpy()
it. I may not be able to use std::map in any case. For all I know it could allocate several pieces of memory.
我能想到的最好的解决方法是足够简单。由于碎片内存管理器会将新的分配放在更有利的位置,所以我需要做的是重新分配它,然后删除旧的:
The best workaround I can think of is simple enough. Due to the fact that the fragmented memory manager will put new allocations at more beneficial locations, all I need to do is allocate it anew and then delete the old:
for(... each instance of A ...) {
stl::map<something>* tmp = a.the_map;
a.the_map = new stl::map<something>(tmp);
delete tmp;
}
无论如何,我想知道:
In any case, this lead me to wonder:
C ++是否有语义或成语将对象移动/复制到特定的内存位置?
Does C++ have semantics or idioms to move/copy an object into a specific memory location?
是否可以将stl容器的内容移动到特定的内存位置?
Is it possible to move the contents of an stl container to a specific memory location?
编辑:虽然我没有指出out,我会明显地传递一个allocator参数到std :: map。基于我得到的信息答案,我意识到我在我的初始问题中发布的解决方法可能是减少碎片的唯一方法。通过使用映射的副本构造函数(和allocator模板参数),映射使用的所有内存都将被正确重新分配。
Although I didn't point it out, I would obviously pass an allocator parameter to std::map. Based on the informative answers I got, I realize the workaround I posted in my initial question would probably be the only way to reduce fragmentation. By using the map's copy constructor (and the allocator template parameter), all memory used by the map would be properly re-allocated.
如注释所指出的,大多是一个理论问题。
As a comment pointed out, this is mostly a theoretical problem. Memory fragmentation is rarely something to worry about.
推荐答案
每次插入一个新的键值对时,地图会分配一个节点存储它。此分配如何发生的详细信息由地图使用的 allocator 确定。
Everytime you insert a new key,value pair the map will allocate a node to store it. The details of how this allocation takes place are determined by the allocator that the map uses.
默认情况下,当您创建地图时,如 std :: map< K,V>
used,它在堆上创建节点(即 new
/ delete
)。
By default when you create a map as in std::map<K,V>
the default allocator is used, which creates nodes on the heap (i.e., with new
/delete
).
您不需要这样做,因此您必须创建一个自定义分配器类,创建由内存管理器指定的节点。
You don't want that, so you'll have to create a custom allocator class that creates nodes as dictated by your memory manager.
创建分配器类并不简单。 说明了如何做,您必须适应它对你自己的需求。
Creating an allocator class is not trivial. This code shows how it can be done, you'll have to adapt it to your own needs.
一旦你有了你的allocator类(假设你叫它 MemManagerAllocator
),你必须定义你的map作为 std :: map< K,V,MemManagerAllocator>
,然后像使用一个常规的地图一样使用它。
Once you have your allocator class (let's say you call it MemManagerAllocator
) you'll have to define your map as std::map<K, V, MemManagerAllocator>
and then use it like you would use a regular map.
个人而言,我需要一个非常糟糕的内存碎片问题来处理所有这些麻烦。
Personally, I would need to have a really bad problem of memory fragmentation to go into all that trouble.
这篇关于将C ++对象(特别是stl容器)移动到特定的内存位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!